B(跳转指令)及BL(带返回的跳转指令)
B指令和BL指令均可以跳转到指令中的目标地址,这两个指令和目标地址处的指令都时ARM指令集。
-
相同之处
二者也可以根据CPSR中条件标志位的值和指令中的执行条件来决定是否执行跳转操作。
-
不同之处
B指令仅仅执行跳转操作;BL指令同时还将PC寄存器的值保存到LR寄存器中。
指令编码格式
31 28 | 27 26 25 | 24 | 23 ----------- 0 |
---|---|---|---|
cond | 1 0 1 | L | signed_immed_24 |
指令的语法格式
B{L} {} <target_address>
其中:
- L决定是否保存返回地址。
- 指令执行的条件码。
- <target_address> 指令跳转的目的地址。范围大致为-32M~+32M。
- 计算方法:
- 将指令中的24位带符号的补码立即数扩展为32为(扩展符号位);
- 将此32位数左移两位;
- 将得到的值加到PC寄存器中,即得到目的地址。
- 计算方法:
指令操作的伪代码
if ConditionPassd(cond) then
if L == 1 then
LR = address of the instruction after the branch instruction
PC = PC + (SignExtend(signed_immed_24) << 2)
指令的使用
BL指令用于实现子程序调用。子程序的返回值可以将LR寄存器的值复制到PC 寄存器中来实现。通常有以下三种方法实现:
- BX R14
- MOV PC,R14
- 当子程序入口中使用了“STMFD R13!,{, R14}”时,可以使用指令“LTMFD R13!,{, PC}”。
ARM汇编器通过以下步骤计算指令编码中的Signed_immed_24。
- 将PC寄存器的值作为本跳转指令的基地址值。
- 从跳转的目标地址中减去上面所说的跳转的基地址值,生成字节偏移量。由于ARM指令时字对齐的,该字节偏移量为4的倍数。
- 当上面生成的字节偏移量超过范围33554432~33554430时,程序需要做相应的处理。
- 否则,将指令编码中的Signed_immed_24设置成上述字节偏移量的bits[25:2]。
当指令跳转越过地址0或32位地址空间的最高地址时,将产生不可预知的结果。
示例
B Label ;程序跳转到标号Label处执行
BCC Label ;当CPSR寄存器中的C条件标志为1时,程序跳转到Label处执行
BL func_1 ;程序跳转到子程序func_1处执行,同时将当前PC值保存到LR中