我希望您能够在基于ARM的微控制器上正确编写SVC调用。根据我目前的理解,ARM具有异常向量表,这意味着任何程序的第一条指令必须是分支到适当处理程序的指令:
RESET ;Handles reset
UNDEFINED ;Undefined instructions
SVC BL SVC_Entry
PRE_ABORT ;Prefetch abort
DAT_ABORT ;Data abort
每次运行SVC指令时,模式会切换为supervisor,提供的数字将存储在R0中,并且程序将分支到适当的处理程序:
;== Handling SVC calls ========================================================
Max_SVC EQU 1
SVC_Entry CMP R0, #Max_SVC ;Check upper limit
BHI SVC_end ;Does nothing if unknown
ADD R0, PC, R0, LSL #2 ;Calculate table address
LDR PC, [R0, #0]
Jump_table DEFW SVC_0 ;Halt
DEFW SVC_1 ;Print string
;== SVC calls ================================================================
SVC_1 B SVC_end
SVC_end MOVS PC, LR ;Exiting
如果我们有以下指令:
ADR R1, string ;R1 points to the string
SVC 1 ;SVC_1 handles the printing
该程序需要切换到监管模式,将数字“1”存储在R0中,然后根据跳转表跳转到SVC_1,运行代码并切回用户模式。
这样正确吗?我操作得对吗?
到目前为止,我遇到的问题是编译器对这行代码报错:“预期操作符”。
SVC BL SVC_Entry
这个话题在互联网上很难找到相关信息,我只是想知道如何在ARM微控制器上正确使用SVC调用。
非常感谢。
编辑:底层处理器是一个时钟频率大约为240 MHz的ARM9。它位于AT91微控制器中。实验板已经被修改以适应我的大学需要。
通过串口,使用自制程序将代码加载到板子上。该程序也允许调试。
SVC: B SVC_Entry
。注意,冒号:
使其成为标签。最好将其命名为 svc_vec,因此svc_vec: b SVC_Entry
。另一个问题是,如果使用 BL,将会破坏用户返回地址。您可以使用R0
或任何您希望建立的约定;检查指令通常很慢。不要忘记设置监管者堆栈和模式。在更改它们之前,您可能希望保存一些用户寄存器;除非您在调用约定中定义了它。 - artless noise