i386汇编器指令编码

时间:2014-04-14 09:10:26

标签: assembly opcode i386

我试图理解为i386 / x86编译的程序中的指令是如何编码的(我使用http://ref.x86asm.net/coder32.html作为参考),但我似乎无法控制这个问题,尽管相反好文档。如果有人可以向我解释这一点,我会非常高兴。

到目前为止,我已经收集到一条指令编码如下:

Prefix (1 byte) [optional]
Opcode (1 or 2 byte, depending on prefix)
ModR/M (1 byte) [optional]
SIB (1 byte) [optional]
Displacement (1-4 bytes) [optional]
Immediate Value (1-4 bytes) [optional]

可选参数取决于要执行的实际操作,resp。操作码。

我们假设我有以下说明,简单明了:

6A 4D     push   4Dh

对我来说没问题,我理解。 6A是具有8字节中间值4Dh的操作码。

让我们走得更远:

51     push    ecx

相同的交易,只有操作码为50 + 1的ECX寄存器作为r32操作数。

但是这个呢?

FF 15 F8 2A 42 00     call   DWORD PTR ds:0x422AF8

据我所知,第一个字节是CALL的操作码,第二个是ModR / M,mod == 00,reg == 010,r / m == 101,它指定了一个位移,即F8 2A 42 00的最后四个字节。

我不明白的是两件事:

首先,根据上面提到的链接中的表格,FF操作码可以有多种用途,例如PUSH,CALL或JMP的变体。唯一的区别似乎是所谓的"操作码扩展",这将是' 2'这里的例子。这编码在哪里?我的反汇编程序如何知道它是CALL的FF,而不是JMP的FF?

其次,为什么这个操作数是DS段的位移?这是指令的默认值,还是在某处编码? segment-override-bytes是否与它有关?

正如你所熟悉的那样,我现在几乎已经注意到了这个领域的新手,我不得不考虑在这里张贴一个帖子,因为有些人会变得有点专横或光顾一个"平淡"问题,但我真的可以在这里使用一些帮助。

如果我对事情的理解是错误的,请纠正我,如果有人关心大致解释编码是如何工作的,我真的很感激。

提前致谢!

3 个答案:

答案 0 :(得分:3)

您应该阅读官方的英特尔指令集参考,而不是那些简洁的在线资料,其中详细解释了所有这些内容。让我引用相关段落:

  

/ digit - 0到7之间的数字表示ModR / M字节   该指令仅使用r / m(寄存器或存储器)操作数。该   reg字段包含提供扩展的数字   指令的操作码。

请注意,在您的情况下,modr / m字节是0x15,您解析错误。它是二进制的0001 0101,表示mod = 00,reg = 010和r / m = 101。如您所见,reg字段确实为2,编码正确的操作码扩展名。

至于段问题:是的,访问内存的指令有一个与之关联的默认段,可以用前缀覆盖。反汇编程序可能会也可能不会显示默认段。如果存在实际覆盖,我个人更喜欢它只显示段。

答案 1 :(得分:2)

在手册中写为/ digit的扩展操作码内容在ModRM字节的R字段中编码。示例中的ModRM字节为15,因此00 010 101您可以看到R字段为2(正如预期的那样)。

ds有默认值,因此未编码。段覆盖与它有关,但在这种情况下不需要覆盖。

请注意,您可以拥有多个前缀,例如段覆盖,操作数大小覆盖,地址大小覆盖和锁定前缀(4个字节的前缀),您甚至可以拥有多余的前缀,并且基本上可以使用多个前缀你想要的,只要你不要让整个指令超过15个字节(非常旧的处理器上的限制更低)。

此外,一些新指令有3个操作码字节,请参阅0F 38 XX0F 3A XX组。

答案 2 :(得分:2)

我喜欢使用英特尔手册中的这些旧表:

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

Format of Postbyte(Mod R/M aus Intel-Doku)
------------------------------------------
MM RRR MMM

MM  - Memeory addressing mode
RRR - Register operand address
MMM - Memoy 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