我正在编写一个反汇编程序,我正在查看指令格式(并手动进行一些反汇编),我遇到了一条我似乎无法解码的指令。
该特定指令的输出(来自 objdump)是:
c6 05 14 a0 04 08 01 movb $0x1,0x804a014
但是,我不明白指令是如何解码的,因为操作码 c6 应该是 MOV Eb Ib (Mod R/M to imm8)。
有人可以告诉我它是如何解码的吗?
谢谢!
我正在编写一个反汇编程序,我正在查看指令格式(并手动进行一些反汇编),我遇到了一条我似乎无法解码的指令。
该特定指令的输出(来自 objdump)是:
c6 05 14 a0 04 08 01 movb $0x1,0x804a014
但是,我不明白指令是如何解码的,因为操作码 c6 应该是 MOV Eb Ib (Mod R/M to imm8)。
有人可以告诉我它是如何解码的吗?
谢谢!
Alex Frunze 的回答(部分)解释了这一点,但他的回答有点简洁,所以我将在这里提供一些解释:
我希望这有帮助。
好吧,转移到即时并不意味着什么。该指令所做的是将常量 1 移入位于 0x804a014 的内存字节中。类似于等效的 C 代码:
*(unsigned char *)0x804a014 = 1;
c6
如您所知,您有 opcode 。您可以将其作为文档第 2A 卷MOV
中说明的一部分进行查找。
是05
ModR/M 字节。您可以使用第 2A 卷的表 2-2,“使用 ModR/M 字节的 32 位寻址形式”来破译它。05
在图表的“ModR/M 字节值(十六进制)”部分中查找。从那里开始跟踪,您会看到此 ModR/M 值的有效地址以“disp32”形式给出。那里的脚注说“disp32 命名法表示跟随 ModR/M 字节的 32 位位移”。在这种情况下,这是指令的下四个字节:14 a0 04 08
.
最后,你有 8 位立即数01
,完整的指令被解码。
c6 - 操作码(Mod/RM 字节中也有一部分操作码,在 /digit(reg) 字段中)
05 - Mod/RM 字节(mod=00b, r/m=101b, /digit(reg)=0 - 部分操作码)
14 a0 04 08 - disp32
01 - imm8
这是一个mov
从Ib
到Eb
。您可能将 objdump 显示反汇编的 AT&T 语法与 Intel/AMD 文档的语法混淆了。AT&T 语法中操作数的顺序与 x86 CPU 手册中的相反。