带有链接指令的'bl'或分支几乎总是变成0xebfffffe
然而,处理器和GNU binutils objdump不知何故知道分支到哪里:
00000000 <init_module>:
0: e1a0c00d mov ip, sp
4: e92ddff0 push {r4, r5, r6, r7, r8, r9, sl, fp, ip, lr, pc}
8: e24cb004 sub fp, ip, #4
c: e24dd038 sub sp, sp, #56 ; 0x38
10: ebfffffe bl 0 <init_module>
14: e59f0640 ldr r0, [pc, #1600] ; 65c <init_module+0x65c>
18: ebfffffe bl 74 <init_module+0x74>
他们怎么知道的?
问题是由于您查看的是对象文件的反汇编,而不是最终可执行文件或共享对象。
汇编程序生成对象文件时,bl
目标的最终地址尚未固定(这取决于将与其链接的其他对象文件)。因此,汇编程序将地址设置为0,但也添加了一个重定位,"告诉"链接器这个bl
应该在最终文件中的位置。(您可以通过添加-r
交换机在objdump
中查看搬迁信息。)
链接时,链接器处理重新定位,计算目标函数的最终地址,并修补指令,使目标地址对齐。如果反汇编最终的链接可执行文件,您将看到不同的操作码。