如何理解 objdump 的输出,关于间接 jmp?
How to understand the output of objdump, about indirect jmp?
objdump -S my_program时,通常可以看到下面的间接jmp指令,一般用于switch/case跳转table:
ffffffff802e04d3: ff 24 d5 38 2e 10 81 jmpq *-0x7eefd1c8(,%rdx,8)
如何理解地址-0x7eefd1c8
?意思是table的基地址是0xffffffff802e04d3 - 0x7eefd1c8
?
此外,如何从 ff 24 d5 38 2e 10 81
中获取 -0x7eefd1c8
?
decoding issue
比你还得看看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's Complement Encoding [3] 编码。
从二进制补码转换得到我们期望的数字:
>>> print hex(0x81102e38 - (1 << 32))
-0x7eefd1c8
当处理器在 64 位模式下执行该指令时,它从 0xffffffff81102e38 + (%rdx * 8)
中读取 8 个字节(原始数字经过符号扩展)并将该四字放入 %rip
[4]。
参考手册:
- 第 2A 卷,第 3.2 节说明 (A-M),第 3-440
页
- 第 2 卷,第 2.1.5 节 ModR/M 和 SIB 字节 的寻址模式编码,第 2-6..2-7 页
- 第 1 卷,第 4.2.1.2 节有符号整数 ,第 4-4
页
- 第 2 卷,第 2.2.1.3 节位移,第 2-11
页
objdump -S my_program时,通常可以看到下面的间接jmp指令,一般用于switch/case跳转table:
ffffffff802e04d3: ff 24 d5 38 2e 10 81 jmpq *-0x7eefd1c8(,%rdx,8)
如何理解地址-0x7eefd1c8
?意思是table的基地址是0xffffffff802e04d3 - 0x7eefd1c8
?
此外,如何从 ff 24 d5 38 2e 10 81
中获取 -0x7eefd1c8
?
decoding issue
比你还得看看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's Complement Encoding [3] 编码。
从二进制补码转换得到我们期望的数字:
>>> print hex(0x81102e38 - (1 << 32))
-0x7eefd1c8
当处理器在 64 位模式下执行该指令时,它从 0xffffffff81102e38 + (%rdx * 8)
中读取 8 个字节(原始数字经过符号扩展)并将该四字放入 %rip
[4]。
参考手册:
- 第 2A 卷,第 3.2 节说明 (A-M),第 3-440 页
- 第 2 卷,第 2.1.5 节 ModR/M 和 SIB 字节 的寻址模式编码,第 2-6..2-7 页
- 第 1 卷,第 4.2.1.2 节有符号整数 ,第 4-4 页
- 第 2 卷,第 2.2.1.3 节位移,第 2-11 页