6

我正在编写一个反汇编程序,我正在查看指令格式(并手动进行一些反汇编),我遇到了一条我似乎无法解码的指令。

该特定指令的输出(来自 objdump)是:

c6 05 14 a0 04 08 01    movb   $0x1,0x804a014

但是,我不明白指令是如何解码的,因为操作码 c6 应该是 MOV Eb Ib (Mod R/M to imm8)。

有人可以告诉我它是如何解码的吗?

谢谢!

4

3 回答 3

5

Alex Frunze 的回答(部分)解释了这一点,但他的回答有点简洁,所以我将在这里提供一些解释:

  1. 操作码为 c6/0,表示该指令有 2 个操作数。一个是 r/m 8,表示以 mod/rm 字节编码的操作数和立即操作数。两个操作数都是 8 位宽。
  2. 操作码中的 /0 表示操作码的一部分被编码在 mod/rm 字节中。mod/rm 字节中的位 3-5 是操作码的一部分。当您有 c6 后跟一个 mod/rm 字节,其位 3-5 的值为 0 时,您会得到一个 mov 操作码。
  3. 值 5(紧跟 c6 的字节)对应于 r/m 字节 00 000 101(二进制)。
  4. r/m 字节的“后三位”(位 0-2)对应于 r/m 字段。r/m 值 101 (5) 表示“使用位移 dword”,因此 mod/rm 字节之后的接下来的 4 个字节形成一个立即地址。
  5. 14 a0 04 08 是 0x0804a014 的小端编码
  6. 最后一个字节 1 是要加载到地址中的立即值

我希望这有帮助。

于 2012-09-11T06:57:20.030 回答
3

好吧,转移即时并不意味着什么。该指令所做的是将常量 1 移入位于 0x804a014 的内存字节中。类似于等效的 C 代码:

*(unsigned char *)0x804a014 = 1;

c6如您所知,您有 opcode 。您可以将其作为文档第 2A 卷MOV中说明的一部分进行查找。

05ModR/M 字节。您可以使用第 2A 卷的表 2-2,“使用 ModR/M 字节的 32 位寻址形式”来破译它。05在图表的“ModR/M 字节值(十六进制)”部分中查找。从那里开始跟踪,您会看到此 ModR/M 值的有效地址以“disp32”形式给出。那里的脚注说“disp32 命名法表示跟随 ModR/M 字节的 32 位位移”。在这种情况下,这是指令的下四个字节:14 a0 04 08.

最后,你有 8 位立即数01,完整的指令被解码。

于 2012-09-11T06:19:55.180 回答
3

c6 - 操作码(Mod/RM 字节中也有一部分操作码,在 /digit(reg) 字段中)
05 - Mod/RM 字节(mod=00b, r/m=101b, /digit(reg)=0 - 部分操作码)
14 a0 04 08 - disp32
01 - imm8

这是一个movIbEb。您可能将 objdump 显示反汇编的 AT&T 语法与 Intel/AMD 文档的语法混淆了。AT&T 语法中操作数的顺序与 x86 CPU 手册中的相反。

于 2012-09-11T06:21:17.910 回答