1. ARM汇编中的子程序调用机制
在ARM架构中,子程序调用是通过分支链接指令BL(Branch with Link)实现的。这条指令实际上完成了两个关键操作:首先将返回地址保存到链接寄存器(LR,通常是R14),然后将程序计数器(PC)设置为目标子程序的起始地址。
1.1 BL指令的工作原理
BL指令的标准语法格式为:
armasm复制BL destination
其中destination通常是子程序第一条指令的标签,也可以是程序相对或寄存器相对的表达式。当处理器执行BL指令时:
- 将下一条指令的地址(即返回地址)存入LR寄存器
- 将PC设置为目标子程序的地址
- 处理器开始从目标地址处执行指令
典型的子程序调用和返回流程如下:
armasm复制main:
MOV r0, #10 ; 设置参数
MOV r1, #20
BL add_numbers ; 调用加法子程序
... ; 继续执行主程序
add_numbers:
ADD r0, r0, r1 ; 执行加法运算
BX lr ; 返回到调用者
1.2 参数传递与寄存器约定
ARM架构定义了一套标准的寄存器使用约定,这对于确保不同模块间的互操作性至关重要:
- 参数传递:R0-R3用于传递子程序的前四个参数
- 返回值:R0用于存放子程序的返回结果
- 寄存器保存:被调用的子程序必须保存它将要修改的R4-R11寄存器
- 链接寄存器:R14(LR)存储返回地址,R15(PC)是程序计数器
重要提示:在混合使用汇编和高级语言时,必须严格遵守ARM的过程调用标准(Procedure Call Standard),否则会导致难以调试的错误。
1.3 子程序返回的多种方式
ARM提供了几种从子程序返回的方法,各有适用场景:
-
BX LR:
armasm复制BX lr ; 最常用的返回指令,可切换ARM/Thumb状态 -
MOV PC, LR:
armasm复制MOV pc, lr ; 早期ARM架构的返回方式,不能切换状态 -
POP {PC}:
armasm复制PUSH {lr} ; 在子程序开头保存LR ... POP {pc} ; 从栈中恢复PC实现返回
在Thumb-2代码中,必须使用BX指令返回,因为MOV PC, LR不能自动处理状态切换。
2. 条件执行机制深度解析
ARM架构最强大的特性之一就是几乎所有的指令都可以条件执行。这种设计大幅提升了代码密度和执行效率,特别适合资源受限的嵌入式系统。
2.1 ALU状态标志寄存器
条件执行的基础是CPSR(Current Program Status Register)中的
