如题。
跳转指令b的机器码格式为0xEAXX XXXX,EA后面的24位带符号的补码立即数经过两个步骤转换为偏移量,加上PC即得到跳转目标地址。
请问从b start_code 到 start_code: 的偏移量是多少啊?
多谢版主的帮助。 通过命令 arm-linux-objdump -S -j .text start.o 得到代码段的反汇编代码如下:
......
.globl _start
_start: b start_code
0: ea000012 b
50 <start_code>
ldr pc, _undefined_instruction
4: e59ff014 ldr pc, [pc, #20] ; 20 <_undefined_instruction>
ldr pc, _software_interrupt
8: e59ff014 ldr pc, [pc, #20] ; 24 <_software_interrupt>
......
00000050 <start_code>:
start_code:
/*
* set the cpu to SVC32 mode
*/
mrs r0, cpsr
50: e10f0000 mrs r0, CPSR
......
分析如下:跳转指令 b start_code 的机器码为 0x EA000012,其中24位带符号的补码立即数 0x000012是用来计算跳转的目标地址即start_code 的地址。start_code 地址的计算方法是:(1) 将该24位补码立即数左移2位扩展为32位(扩展其符号位)(由于是正整数,所以扩展后仍为0x12,但已变成32位数);(2) 将此32位数左移两位变成0x48(
相当于乘以4,这是因为32位地址是4个字节);(3) 将得到的值加到PC寄存器中,即得到跳转的目标地址。反汇编代码中start_code的地址是0x50,所以PC寄存器中的值是0x8, 也就是说执行 b start_code 的时候,PC寄存器中存放的已经是第三条指令的地址了,这应该是由于指令流水线和指令预取的缘故。 0x48 + 0x8 = 0x50,说明第一行可执行代码 b start_code的机器码的确是0xEA000012没错。
[ 此帖被bianyun1981在2011-01-19 09:16重新编辑 ]