ARM System Calls
Zhang3(讨论 | 贡献)2022年2月8日 (二) 09:44的版本 (创建页面,内容为“{{Template:In Progress}} ==System Calls== <pre>swi 0x420000</pre> 这里向你介绍如何在ARM上做System Call。 指令 <span style="font-family:monospace">swi</span> 跳转到预定义的地址,该地址又跳转到System Call处理程序。 System Call处理程序执行特定函数,并返回用户代码: <pre>mov pc, lr</pre> 在大多数情况下,您无需担心从中断返回,因为GCC设置为针对ARM交叉编译,可以在C中编写中断…”)
System Calls
swi 0x420000
这里向你介绍如何在ARM上做System Call。 指令 swi 跳转到预定义的地址,该地址又跳转到System Call处理程序。 System Call处理程序执行特定函数,并返回用户代码:
mov pc, lr
在大多数情况下,您无需担心从中断返回,因为GCC设置为针对ARM交叉编译,可以在C中编写中断处理程序:
void swi_handler () __attribute__((interrupt));
= 创建System Call =
interrupt_vector_table: b . @ Reset Handler b . @ Undefined b . @ SWI Handler b . @ Prefetch Abort b . @ Data Abort b . @ IRQ b . @ FIQ
这是相当于在x86上IDT的ARM版,它默认存储在地址0。 我们需要关心的唯一条目是SWI Handler。 要安装我们自己的SWI Handler,我们替换 b . 带有分支到我们的处理程序的指令:
interrupt_vector_table: b . @ Reset Handler b . @ Undefined b swi_handler @ Our new SWI Handler b . @ Prefetch Abort b . @ Data Abort b . @ IRQ b . @ FIQ
我们可以像这样编码中断处理程序:
void __attribute__ ((interrupt ("SWI"))) swi_handler (void) {}
ARM上函数的参数,在寄存器r0-r3中传递,如果遵循相同的约定的System Call,那么我们的中断处理程序也可以获取参数:
void __attribute__ ((interrupt ("SWI"))) swi_handler (int r0, int r1, int r2, int r3) {}
您可能已经注意到 swi 采用整数参数。 为了在C中得到这个参数,我们必须这样做:
uint8_t int_vector = 0;
asm volatile ("ldrb %0, [lr, #-2]" : "=r" (int_vector));
这会将参数的高8位 (16-23) 加载到 int_vector 中,使用Thumb加载完整的24位将不起作用。