x86 OpCode指令解码

时间:2014-10-28 11:41:59

标签: assembly x86 reverse-engineering disassembly isa

我一直在研究x86架构的软件开发人员手册,试图刷新我的逆向工程技能。我知道这个架构很复杂,并且与前几代产品向后兼容。随着新一代的发展,一些较旧的文档部分被遗漏了。但其中一个令人不安的解释和误解是与此类似的指示:

80 /2 ib

因此,基于以下80 OpCode的指令后面会跟一个MOD / RM / REG字节。 无视旧内容的副作用之一,我不知道不同版本的MOD / RM / REG字节。 但我总是认为他们的差异是由于8/16位的架构根源。值得庆幸的是,我在最初的架构介绍中偶然发现了MOD / RM / REG字节的解析。

因此,上面提供的指令后跟正斜杠数字表示八进制值将包含在MOD / RM / REG字节的RM偏移量内,其值为2

我的实际问题如下:

MOD / RM / REG字节中的MOD偏移是否接受当前条件下的所有寻址模式或是否存在任何限制? 另一件事是否有人知道为什么数字是用/2指定的?这是一个理由,可以假设较低的值在较老的ISA中使用,因此可以保留以便向后兼容。

2 个答案:

答案 0 :(得分:3)

您应该阅读手册中的第2章指令格式。 作为简要摘要,/digit表示法使用reg/opcode字节的modr/m字段作为给定值的操作码扩展。手册说: reg / opcode字段指定一个寄存器号或三个以上的操作码信息。。另请参阅表2-2。带ModR / M字节的32位寻址表

当没有第二个寄存器操作数时使用操作码扩展,例如对于immediates,如在您的示例中为ADC r/m8, imm8。主操作码80存在其他说明,但扩展名不同。您可以查看表A-6。按组编号的单字节和双字节操作码的操作码扩展,并看到0到7的操作码扩展名对应ADDORADC,{{分别为1}},SBBANDSUBXOR

还要注意modr / m,因此这种编码方案也用于32位和64位代码,所以它不是过时的。例如,CMP包含机器代码ADC [eax], 0x42,其中80 10 42是主要操作码,80是注册字段中带有10的modr / m,指定2,当然[eax]是直接的。

答案 1 :(得分:2)

Instruction Prefix                0 or 1 Byte
Address-Size Prefix               0 or 1 Byte
Operand-Size Prefix               0 or 1 Byte
Segment Prefix                    0 or 1 Byte
Opcode                            1 or 2 Byte
Mod R/M                           0 or 1 Byte
SIB, Scale Index Base (386+)      0 or 1 Byte
Displacement                      0, 1, 2 or 4 Byte (4 only 386+)
Immediate                         0, 1, 2 or 4 Byte (4 only 386+)

Format of Postbyte(Mod R/M byte from Intel-manual)
--------------------------------------------------
MM RRR MMM

MM  - Memory addressing mode
RRR - Register operand address
MMM - Memory operand address

RRR Register Names
Filds  8bit  16bit  32bit
000    AL     AX     EAX
001    CL     CX     ECX
010    DL     DX     EDX
011    Bl     BX     EBX
100    AH     SP     ESP
101    CH     BP     EBP
110    DH     SI     ESI
111    BH     DI     EDI

---

16bit memory (No 32 bit memory address prefix)
MMM   Default MM Field
Field Sreg     00        01          10             11=MMM is reg
000   DS       [BX+SI]   [BX+SI+o8]  [BX+SI+o16]
001   DS       [BX+DI]   [BX+DI+o8]  [BX+DI+o16]
010   SS       [BP+SI]   [BP+SI+o8]  [BP+SI+o16]
011   SS       [BP+DI]   [BP+DI+o8]  [BP+DI+o16]
100   DS       [SI]      [SI+o8]     [SI+o16]
101   DS       [DI]      [DI+o8]     [SI+o16]
110   SS       [o16]     [BP+o8]     [BP+o16]
111   DS       [BX]      [BX+o8]     [BX+o16]
Note: MMM=110,MM=0 Default Sreg is DS !!!!

32bit memory (Has 67h 32 bit memory address prefix)
MMM   Default MM Field
Field Sreg     00        01          10             11=MMM is reg
000   DS       [EAX]     [EAX+o8]    [EAX+o32]
001   DS       [ECX]     [ECX+o8]    [ECX+o32]
010   DS       [EDX]     [EDX+o8]    [EDX+o32]
011   DS       [EBX]     [EBX+o8]    [EBX+o32]
100   SIB      [SIB]     [SIB+o8]    [SIB+o32]
101   SS       [o32]     [EBP+o8]    [EBP+o32]
110   DS       [ESI]     [ESI+o8]    [ESI+o32]
111   DS       [EDI]     [EDI+o8]    [EDI+o32]
Note: MMM=110,MM=0 Default Sreg is DS !!!!

---

SIB is (Scale/Base/Index)
SS BBB III
Note: SIB address calculated as:
<sib address>=<Base>+<Index>*(2^(Scale))

Fild   Default Base
BBB    Sreg    Register   Note
000    DS      EAX
001    DS      ECX
010    DS      EDX
011    DS      EBX
100    SS      ESP
101    DS      o32        if MM=00 (Postbyte)
SS      EBP        if MM<>00 (Postbyte)
110    SS      ESI
111    DS      EDI

Fild  Index
III   register   Note
000   EAX
001   ECX
010   EDX
011   EBX
100              never Index SS can be 00
101   EBP
110   ESI
111   EDI

Fild Scale coefficient
SS   =2^(SS)
00   1
01   2
10   4
11   8