ARM汇编与C语言函数的相互调用及参数传递
汇编调用C函数参数传递规则
前4个参数通过寄存器 R0
-R3
传递,超出部分从右向左压栈。32位返回值存于 R0
,64位整数用 R0
和 R1
,浮点数通过 S0
/D0
返回。
示例:ARM汇编调用C函数
assembly
.global _start
.extern c_function ; 声明外部C函数
_start:
MOV R0, #10 ; 参数1
MOV R1, #20 ; 参数2
BL c_function ; 调用函数
B . ; 循环
对应的C函数:
c
int c_function(int a, int b) {
return a + b; // 返回值通过R0返回
}
C调用汇编函数参数传递规则
规则与汇编调用C一致,前4个参数使用 R0
-R3
。汇编函数需用 .global
导出。
示例:C调用ARM汇编函数
C代码声明:
c
extern int asm_function(int a, int b);
int main() {
asm_function(10, 20); // 调用汇编函数
return 0;
}
汇编实现:
assembly
.global asm_function
asm_function:
ADD R0, R0, R1 ; R0 = a + b
BX LR ; 返回
关键注意事项
- 若修改
R4
-R11
,需在汇编中压栈保存。 BL
指令自动保存返回地址到LR
(R14)。
ARM内核异常类型及工作模式切换
异常类型与对应模式
异常类型 | 触发条件 | 进入模式 | 优先级 |
---|---|---|---|
复位(Reset) | 上电或硬件复位 | 管理模式(SVC) | 1 |
数据中止(Data Abort) | 非法内存访问(如缺页) | 中止模式(ABT) | 2 |
快速中断(FIQ) | 高优先级外设中断(如DMA) | FIQ模式 | 3 |
普通中断(IRQ) | 常规外设中断(如定时器) | IRQ模式 | 4 |
预取中止(Prefetch Abort) | 指令预取失败 | 中止模式(ABT) | 5 |
软件中断(SWI/SVC) | SVC 指令触发(系统调用) |
管理模式(SVC) | 6 |
未定义指令 | 执行未知指令 | 未定义模式(UND) | 7 |
关键机制
- 异常向量表 :固定入口地址(如复位地址为
0x00000000
)。 - 模式切换 :异常触发时自动切换模式,保存
CPSR
到SPSR
。 - 寄存器组 :不同模式拥有独立的
SP
(R13)和LR
(R14)。
IRQ处理示例
assembly
IRQ_Handler:
SUB LR, LR, #4 ; 修正返回地址(PC+4)
PUSH {R0-R12, LR} ; 保存寄存器现场
BL C_IRQ_Handler ; 调用C处理函数
POP {R0-R12, PC}^ ; 恢复现场并返回(^恢复CPSR)
注意事项
- FIQ模式有专用寄存器(
R8
-R12
),可减少保存开销。 - 复位异常不返回,直接初始化系统。
- 中止异常需处理内存错误后重新执行指令。
总结
- ARM与C交互 :严格遵循ATPCS规范,参数通过寄存器和栈传递,返回值使用
R0
。 - 异常处理:7种异常对应不同特权模式,通过向量表跳转,优先级固定。