我有 32 位操作码:FF 35 0E 20 40 00
. 有没有人知道一个很好的操作码表来回答这个问题?(我知道我可以使用反汇编程序,但我想知道如何使用操作码表来确定这一点)。我找到了这个网页,但有 7 种不同的解决方案FF
。我不明白。
2 回答
你找错地方了。您应该在 Intel 或 AMD 的官方文档中查看。
Appendix A Opcode Map
of Vol 2B
ofIntel® 64 and IA-32 Architectures Software Developer’s Manual Combined Volumes: 1, 2A, 2B, 3A and 3B
说那FF
是INC/DEC Grp5
1A
。
Table A-6 Opcode Extensions for One- and Two-byte Opcodes by Group Number
ofVol 2B
表示FF
/ , , , , , ,Group 5
中的任何一个,取决于字节的第 5 位到第 3 位,即后面的字节。(0x35>>3)&7=6 或二进制的 110。所以,这是.INC
DEC
CALLN
CALLF
JMPN
JMPF
PUSH
ModR/M
PUSH Ev
Chapter 2 Instruction Format
ofVol 2A
解释指令由哪些部分组成,包括那些ModR/M
字节和不包括哪些部分。
Appendix A Using Opcode Tables
ofVol 2B
告诉你E
:
ModR/M 字节跟随操作码并指定操作数。操作数要么是通用寄存器,要么是内存地址。如果它是一个内存地址,则该地址是根据段寄存器和以下任何值计算得出的:基址寄存器、索引寄存器、比例因子、位移。
它还告诉您v
:
字、双字或四字(在 64 位模式下),取决于操作数大小属性。
因此,您知道这Ev
意味着寄存器或内存操作数,并且由于这是针对 32 位代码并且没有指令前缀,因此操作数大小为 32 位。因此,Ev
内存中的 32 位寄存器或 32 位变量。
现在你需要找出从 ModR/M 到结尾的其余字节。
看看。Figure 2-1. Intel 64 and IA-32 Architectures Instruction Format
_ Vol 2A
它告诉你在ModR/M
=0x35 中:
Mod
= 00(二进制)
Reg
= 110(二进制;我们之前已经提取了这 3 位)
R/M
= 101(二进制)
Table 2-2. 32-Bit Addressing Forms with the ModR/M Byte
ofVol 2A
告诉你Mod
= 00 和R/M
= 101 意味着disp32
,IOW,指令中有一个由 32 位位移组成的内存操作数。
该字节的Reg
字段ModR/M
已用于选择七条指令之一,因此该字段不编码寄存器操作数。
所以,你的指令是PUSH DWORD [0x0040200E]
。
这与我的反汇编程序输出一致。
让我们尝试一次一个字节地遍历这个字节序列。
- 第一个字节是
FF
. 在英特尔指令集参考中的操作码映射中查找它告诉我们这是一条INC
或一条DEC
指令,以及神秘的“Grp 5 - 1A”。1A 表示“ModR/M 字节的第 5、4 和 3 位用作操作码扩展”。ModR/M 字节是对用于该指令的操作数的源和地址进行编码的字节。在这种情况下,这三位用于扩展操作码。 - 下一个字节是
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 位模式下):有效地址由 a 指定disp32
,这意味着应该跟随 32 位位移ModR/M 字节。指定寄存器的部分说ESI
应该使用,但在这种情况下,此字段用于操作码扩展,因此它不用于表示寄存器源操作数。 - 接下来的四个字节是 32 位位移。
0E 20 40 00
,当解码为小端时,表示0x40200e
。这是将用于该指令的操作数的地址。
综上所述,我们得到了,FF 35 0E 20 40 00
即PUSH DWORD [0x40200e]
它将从地址读取的 32 位值压入0x40200e
堆栈。