7. 分支指令

这些指令会使执行跳转到通常由标签指定的目标位置(参见 label() 汇编指示符)。条件分支以及 itite 指令会测试应用程序状态寄存器(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) 以从子程序返回。对于嵌套子程序,必须在执行内层子程序调用之前保存外层作用域的链接寄存器(通常保存在栈上)。