7. 分支指令¶
这些指令会使执行跳转到通常由标签指定的目标位置(参见 label() 汇编指示符)。条件分支以及 it 和 ite 指令会测试应用程序状态寄存器(APSR)的 N(负)、Z(零)、C(进位)和 V(溢出)标志,以确定是否应执行该分支。
大多数公开的汇编指令(包括 move 操作)都会设置这些标志,但也有专门的比较指令用于测试值。
关于条件标志含义的更多细节,请参见 comparison instructions 章节。
7.1. 文档约定¶
记法:Rm 表示 ARM 寄存器 R0-R15。LABEL 表示用 label() 汇编指示符定义的标签。<condition> 表示下列条件说明符之一:
eq 等于(结果为零)
ne 不等于
cs 进位置位
cc 进位清除
mi 负(negative)
pl 正(positive)
vs 溢出置位
vc 溢出清除
hi > (无符号比较)
ls <= (无符号比较)
ge >= (有符号比较)
lt < (有符号比较)
gt > (有符号比较)
le <= (有符号比较)
7.2. 分支到标签¶
b(LABEL) 无条件分支
beq(LABEL) 相等则分支
bne(LABEL) 不相等则分支
bge(LABEL) 大于或等于则分支
bgt(LABEL) 大于则分支
blt(LABEL) 小于 (<) 则分支(有符号)
ble(LABEL) 小于或等于 (<=) 则分支(有符号)
bcs(LABEL) 进位标志置位则分支
bcc(LABEL) 进位标志清除则分支
bmi(LABEL) 为负则分支
bpl(LABEL) 为正则分支
bvs(LABEL) 溢出标志置位则分支
bvc(LABEL) 溢出标志清除则分支
bhi(LABEL) 较高则分支(无符号)
bls(LABEL) 较低或相等则分支(无符号)
7.3. 长分支¶
上面列出的分支指令所产生的代码使用固定的位宽来指定分支目标,该目标是相对于 PC 的。因此在分支指令距离其目标较远的长程序中,汇编器会产生"branch not in range"错误。这可以通过"wide"变体来克服,例如
beq_w(LABEL) 相等则长分支
宽分支使用 4 字节来编码指令(相比之下,标准分支指令为 2 字节)。
7.4. 子程序(函数)¶
进入子程序时,处理器将返回地址保存在寄存器 r14 中,r14 也称为链接寄存器(lr)。返回到子程序调用之后的指令是通过用链接寄存器更新程序计数器(r15 或 pc)来完成的。这一过程由以下指令处理。
bl(LABEL)
将执行转移到 LABEL 之后的指令,并将返回地址保存在链接寄存器(r14)中。
bx(Rm) 分支到由 Rm 指定的地址。
通常发出 bx(lr) 以从子程序返回。对于嵌套子程序,必须在执行内层子程序调用之前保存外层作用域的链接寄存器(通常保存在栈上)。