40087e: 48 8b 05 cb 01 20 00 mov 0x2001cb(%rip),%rax # 600a50 <__CTOR_LIST__+0x8>
以上是objdump的输出。
但是我想知道48 8b 05 cb 01 20 00
的哪一部分代表mov
, 0x2001cb(%rip)
…
也就是说,是否有工具可以分解机器码?
00 00 00 00 00 00 00 00 00 00 0
48是REX prefix
,通常用于指示指令操作数(寄存器或内存位置)应该是64位而不是32位(即该指令中的RAX而不是EAX)。REX前缀也用于操作R8到R15寄存器的指令。
8b
是MOV指令opcode
。其他值用于其他指令。例如,2b表示SUB, 8d表示LEA。
05
是ModR/M
字节,在64位模式下表示RIP+disp32
内存寻址(而不是32位模式下的disp32
)。这是在字节的Mod
和R/M
位字段中编码的。该字节的Reg
位字段还告诉使用RAX寄存器作为另一个操作数。
cb, 01, 20 and 00
构成disp32
部分的内存操作数,这个位移等于2001CBH
。
把这一切放在一起,我们到达MOV RAX, [RIP+2001CBH]
。
有几种解码指令的方法:
- 使用Intel或AMD的CPU手册手动修改带有独立反汇编器的
- ,例如
ndisasm
,它与NASM 一起出现 - 与您最喜欢的调试器;只要把感兴趣的指令的字节放在程序内存的某个地方(你可以输入它们),然后让反汇编器向你展示该指令的反汇编位置