操作码FF350E204000有什么作用?

时间:2013-03-04 19:55:41

标签: assembly x86 opcode

我有32位操作码:FF 35 0E 20 40 00。有人知道一个好的OpCode表给出了答案吗? (我知道我可以使用反汇编程序,但我想知道,如何使用操作码表来确定它)。我找到了this网页,但FF有7种不同的解决方案。我没有得到它。

2 个答案:

答案 0 :(得分:15)

你正在寻找错误的地方。您应该在英特尔或AMD的官方文档中查看此内容。

<{1}} Appendix A Opcode Map Vol 2B的{​​{1}}表示Intel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 3A and 3BFF INC/DEC Grp5

1A的{​​{1}} Table A-6 Opcode Extensions for One- and Two-byte Opcodes by Group Number Vol 2B / FF Group 5INCDECCALLN },CALLFJMPNJMPF,取决于PUSH字节的第5位到第3位,后面的字节。 (0x35&gt;&gt; 3)&amp; 7 = 6或110二进制。所以,这是ModR/M

PUSH Ev的{​​p> Chapter 2 Instruction Format解释了指令包含哪些部分,包括那些Vol 2A个字节,哪些不是。

ModR/M的{​​p> Appendix A Using Opcode Tables告诉您Vol 2B

  

操作码后面有一个ModR / M字节并指定操作数。操作数是通用寄存器或存储器地址。如果是存储器地址,则从段寄存器和以下任何值计算地址:基址寄存器,索引寄存器,缩放因子,位移。

它还会告诉您E

  

字,双字或四字(在64位模式下),具体取决于操作数大小属性。

因此,您知道v表示寄存器或内存操作数,因为这是针对32位代码而没有指令前缀,操作数大小为32位。所以,Ev是32位寄存器或内存中的32位变量。

现在你需要从ModR / M中找出剩下的字节直到结束。

查看Ev的{​​{1}}。它告诉你在Figure 2-1. Intel 64 and IA-32 Architectures Instruction Format = 0x35:

Vol 2A = 00(二进制)
ModR/M = 110(二进制;我们之前提取了这3位)
Mod = 101(二进制)

Reg的{​​p> R/M告诉您Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte = 00而Vol 2A = 101表示Mod,IOW,有一个由32-组成的内存操作数指令中的位移位。

R/M字节的disp32字段已用于选择七条指令中的一条,因此该字段不对寄存器操作数进行编码。

所以,你的指示是Reg

这与我的反汇编输出一致。

答案 1 :(得分:14)

让我们一次尝试一个字节的字节序列。

  1. 第一个字节是FF。在英特尔指令集参考中的操作码映射中查找它告诉我们这是一个INCDEC指令,以及密码“Grp 5 - 1A”。 1A表示“用作操作码扩展的ModR / M字节的第5位,第4位和第3位”。 ModR / M字节是编码源的字节和用于该指令的操作数的地址。在这种情况下,这三个位用于扩展操作码。
  2. 下一个字节是35。这是ModR / M字节,通常出现在操作码本身之后,在使用它的指令中。 35(十六进制)是二进制的00110101,因此第5位,第4位和第3位是110。在操作码扩展表(表A-6)中查看这一点,我们可以看到这意味着这是一个PUSH d64 Ev指令。 d64脚注表示“在64位模式下,指令默认为64位操作数大小,不能编码32位操作数大小。”。这是PUSH指令的预期。 Ev是一个指定操作数编码的符号 - 最重要的是,它指出ModR / M字节跟在操作码本身之后。另一方面,v表示操作数的大小取决于操作数大小属性。我们已经有了ModR / M字节,所以让我们对其进行解码(表2-2,假设此代码以32位模式运行):有效地址由disp32指定,这意味着32位移应遵循ModR / M字节。指定寄存器的部分表示应该使用ESI,但在这种情况下,该字段用于操作码扩展,因此它不用于表示寄存器源操作数。
  3. 接下来的四个字节是32位位移。 0E 20 40 00,在解码为小端时,表示0x40200e。这是将用于此指令的操作数的地址。
  4. 总结一下,我们得到FF 35 0E 20 40 00PUSH DWORD [0x40200e],即它将推送从堆栈上的地址0x40200e读取的32位值。