直接使用跳转指令(B)
b reset b undefined_instruction b software_interrupt b prefetch_abort b data_abort b not_used b irq b fiq /* ... */
反汇编后是这个样子的(链接时的起始地址为0x33f80000):
33f80000 <.text>: 33f80000: ea000006 b 33f8002033f80004: ea000006 b 33f80024 33f80008: ea000006 b 33f80028 33f8000c: ea000006 b 33f8002c 33f80010: ea000006 b 33f80030 33f80014: ea000006 b 33f80034 33f80018: ea000006 b 33f80038 33f8001c: ea000006 b 33f8003c 33f80020: eafffffe b 33f80020 33f80024: eafffffe b 33f80024 33f80028: eafffffe b 33f80028 33f8002c: eafffffe b 33f8002c 33f80030: eafffffe b 33f80030 33f80034: eafffffe b 33f80034 33f80038: eafffffe b 33f80038 33f8003c: eafffffe b 33f8003c
分析B指令:
Branch instruction contains a signed 2's complement 24 bit offset. This is shifted left two bits, sign extended to 32
bits, and added to the PC. The instruction can therefore specify a branch of +/- 32Mbytes. The branch offset must
take account of the prefetch operation, which causes the PC to be 2 words (8 bytes) ahead of the current instruction.
Branch指令包含了一个24位的二进制补码。将二进制补码左移两位,带符号扩展为32位,然后与PC相加。所以指令能够跳转的空间为±32M
在计算PC值得时候,要考虑到指令预取,PC的值为当前指令值加2 word(8字节)。
第一条指令的二进制码为0xea000006,对照B指令的格式,可以得出:
Cond = 1110 always,也就是无条件执行
L = 0 不需要保存PC
Offset = 0x06
则跳转后的PC值为:
PC = PC + 0x06<<2 = PC + 24。
如果当前程序运行于0地址,则 PC = 0 + 8 + 24 = 32 = 0x20,此时0x20存储的为reset指令,可以正确跳转。
如果当前程序运行于0x33f80000,则 PC = 0x33f80000 + 8 + 24 = 0x33f80020,此时0x33f80020存储的为reset指令,可以正确跳转。
所以得出结论:B可以在±32M空间内跳转,且为位置无关指令。
PS:位置无关指令的意思是,无论代码实际运行的物理地址是哪里,都可以正确执行。
相关文章