当objdump -S my_program时,通常我可以看到以下间接jmp指令,它通常用于切换/案例跳转表:
ffffffff802e04d3: ff 24 d5 38 2e 10 81 jmpq *-0x7eefd1c8(,%rdx,8)
如何理解地址-0x7eefd1c8
?这意味着表的基地址是0xffffffff802e04d3 - 0x7eefd1c8
?
另外,如何从-0x7eefd1c8
获取ff 24 d5 38 2e 10 81
?
答案 0 :(得分:3)
解码问题
比你必须看Intel Development Manuals
ff
是JMP操作码(跳近,绝对间接)[1] 24
是 ModR / M 字节[2],这意味着 SIB 字节在它之后(JMP操作码只有一个操作数,因此寄存器字段被忽略了)d5
是一个 SIB 字节[2],这意味着 disp32 在此之后,Scale = 8
和Index = %rdx
(在32位模式,索引应为%edx
),没有基础。38 2e 10 81
是一个4字节的 disp32 操作数。如果您将其编码为双字,则会0x81102e38
注意最高位设置为1
。这是一个符号位,意味着值在 Two的补码编码 [3]中编码。 从两个补码转换得到我们预期的数字:
>>> print hex(0x81102e38 - (1 << 32))
-0x7eefd1c8
当处理器在64位模式下执行该指令时,它从0xffffffff81102e38 + (%rdx * 8)
读取8个字节(原始数字是符号扩展的)并将该四字字放入%rip
[4]。
参考手册: