'BL' ARM指令的反汇编是如何工作的?

10

'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>

他们怎么知道?
1个回答

13
问题的原因是您正在查看目标文件的反汇编,而不是最终的可执行文件或共享对象。
当汇编器生成目标文件时,bl 目标的最终地址尚未确定(它取决于将与其链接的其他目标文件)。因此,汇编器将地址设置为0,但还添加了一个重定位项,告诉链接器在最终文件中应该放置这个 bl。 (您可以通过添加 -r 开关在 objdump 中查看重定位信息。)
在链接时,链接器处理重定位项,计算目标函数的最终地址,并修补指令,使目标地址对齐。如果您反汇编最终链接的可执行文件,将会看到不同的操作码。

谢谢(спасибо)。该文件是一个内核模块。我原以为它是一个最终的、链接的可执行文件,但显然不是这样。-r开关就是我要找的。 - yanychar
1
它是部分链接的;内核导入的符号在加载时由内核加载程序解析。 - Igor Skochinsky

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接