在重定位过程中,一般使用位置无关的代码,也即使用相对跳转指令。如:bl main
下面我们就跳转指令的位置无关代码和位置相关代码进行比较。
...
bl main
ldr pc, =main
...
经过反汇编之后,我们得如下代码:
...
5000001c: eb00002f bl 500000e0 <main>
50000020: e59ff004 ldr pc, [pc, #4] ; 5000002c <halt+0x8>
...
5000002c: 500000e0 .word 0x500000e0
...
500000e0 <main>:
500000e0: e92d4800 push {fp, lr}
500000e4: e28db004 add fp, sp, #4 ; 0x4
...
一、
由 bl main 生成的机器码:eb00002f的2进制表示为1110 1011 0000 0000 0000 0000 0010 1111, 其中b[31:28]是条件标志位,
b[27:25]=101表示这是一条跳转指令,b[24]如果设置为1,则返回地址被保存于R14寄存器中;如果为0,表示不保存返回地址。
b[23:0]为一个有符号数,表示跳转的目标地址。其计算规则如下:
1. Sign-extending the 24-bit signed (two's complement) immediate to 30 bits.
2. Shifting the result left two bits to form a 32-bit value.
3. Adding this to the contents of the PC, which contains the address of the branch instruction plus 8 bytes.
用上述规则我们得到跳转的目标地址为(0x2f << 2)+ 8 + 0x1c = 0xe0. 此时,程序跳到0xe0处执行。
二、
由ldr pc, =main生成的反汇编代码 ldr pc, [pc, #4]。此时,pc = 0x20 + 8 + 4 = 0x2c, 即 pc = [0x2c] = 0x500000e0, 于是跳到0x500000e0
处执行,而此时尚未重定位,故此地址不存在,因此将发生错误。
由上可见,bl指令使用的是“PC+偏移值”的方式跳转,属于相对跳转指令,而位置相关的代码采用的是直接将跳转地址加载到PC中,这样的过程在重定位前往往是会发生错误的。因此代码在重定位前必须使用位置无关的指令。
下面我们就跳转指令的位置无关代码和位置相关代码进行比较。
...
bl main
ldr pc, =main
...
经过反汇编之后,我们得如下代码:
...
5000001c: eb00002f bl 500000e0 <main>
50000020: e59ff004 ldr pc, [pc, #4] ; 5000002c <halt+0x8>
...
5000002c: 500000e0 .word 0x500000e0
...
500000e0 <main>:
500000e0: e92d4800 push {fp, lr}
500000e4: e28db004 add fp, sp, #4 ; 0x4
...
一、
由 bl main 生成的机器码:eb00002f的2进制表示为1110 1011 0000 0000 0000 0000 0010 1111, 其中b[31:28]是条件标志位,
b[27:25]=101表示这是一条跳转指令,b[24]如果设置为1,则返回地址被保存于R14寄存器中;如果为0,表示不保存返回地址。
b[23:0]为一个有符号数,表示跳转的目标地址。其计算规则如下:
1. Sign-extending the 24-bit signed (two's complement) immediate to 30 bits.
2. Shifting the result left two bits to form a 32-bit value.
3. Adding this to the contents of the PC, which contains the address of the branch instruction plus 8 bytes.
用上述规则我们得到跳转的目标地址为(0x2f << 2)+ 8 + 0x1c = 0xe0. 此时,程序跳到0xe0处执行。
二、
由ldr pc, =main生成的反汇编代码 ldr pc, [pc, #4]。此时,pc = 0x20 + 8 + 4 = 0x2c, 即 pc = [0x2c] = 0x500000e0, 于是跳到0x500000e0
处执行,而此时尚未重定位,故此地址不存在,因此将发生错误。
由上可见,bl指令使用的是“PC+偏移值”的方式跳转,属于相对跳转指令,而位置相关的代码采用的是直接将跳转地址加载到PC中,这样的过程在重定位前往往是会发生错误的。因此代码在重定位前必须使用位置无关的指令。