'BL'臂指令拆卸如何工作?

yan*_*har 9 linux arm disassembly

'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>
Run Code Online (Sandbox Code Playgroud)

他们怎么知道的?

Igo*_*sky 12

问题是由于您正在查看目标文件的反汇编,而不是最终的可执行文件或共享对象.

当汇编程序生成目标文件时,bl目标的最终地址尚未修复(它取决于将与其链接的其他目标文件).因此汇编程序将地址设置为0,但也添加了一个重定位,告诉链接器bl应该将其放在最终文件中.(您可以objdump通过添加-r开关来查看重定位信息.)

链接时,链接器处理重定位,计算目标函数的最终地址并修补指令,以便目标地址对齐.如果您反汇编最终的链接可执行文件,您将看到不同的操作码.