【问题标题】:How to interpret x86 opcode map?如何解释 x86 操作码映射?
【发布时间】:2015-04-24 05:59:33
【问题描述】:

查看 x86 操作码映射如下:

http://www.mlsite.net/8086/#tbl_map1

它定义了映射,例如:

00: ADD Eb,Gb
01: ADD Ev,Gv
...

该链接对字母的含义进行了基本描述,例如:

  • E:ModR/M 字节跟随操作码并指定操作数。操作数要么是通用寄存器,要么是内存地址。如果它是内存地址,则地址是根据段寄存器和以下任何值计算得出的:基址寄存器、索引寄存器、位移。
  • b:字节参数。

但它有点太模糊了。您如何将其实际转换为“完整的操作码”(整个指令+操作码中的参数)?也无法从Intel manuals 中弄清楚,也许我找错了地方(而且有点不知所措)?看到一个 sn-p 显示输入指令的输出操作码(以及你是如何做到的)会非常有帮助。

【问题讨论】:

  • 无论如何,请使用英特尔手册。对于每条指令,它都给出了机器代码,第 2 章对指令格式进行了非常详细的描述。
  • 不确定你在问什么;英特尔参考手册正是这样做的。您发布的链接似乎通过引入没人使用的术语使事情过于复杂。
  • @duskwuff 你确定吗?我以为x86 was totally retrocompatible
  • @m0skit0 8086 的操作码映射不一定包含自 1978 年 8086 发布以来添加或更改的大量 x86 指令。
  • @duskwuff 我明白了,我误解了你。我认为一个更好的词是不完整

标签: assembly x86 machine-code


【解决方案1】:

请务必使用英特尔手册。对于每条指令,它都给出了机器代码,第 2 章对指令格式进行了非常详细的描述。

但为了给你一个演练,让我们看看ADD EDX, [EBX+ECX*4+15h]。 首先我们通读章节2 指令格式3.1 解释指令参考页 以了解我们将看到的内容。我们对3.1.1.3 Opcode Summary Table 中的指令列中列出的缩写特别感兴趣

有了这些信息,我们转到描述ADD 指令的页面,并尝试为我们要编码的指令确定一个合适的版本。我们的第一个操作数是一个 32 位的寄存器,第二个是一个 32 位的内存位置,所以让我们看看有什么匹配的。它将是倒数第二行:03 /r ADD r32, r/m32。我们回到指令摘要表中的3.1.1.1 操作码列(不带 VEX 前缀的指令)一章,看看那个神奇的/r 是什么:表示 ModR/M 字节的指令包含一个寄存器操作数和一个 r/m 操作数。

好的,图 2-1。英特尔 64 和 IA-32 架构指令格式向我们展示了指令的外观。到目前为止,我们知道我们不会有任何前缀,操作码将是03,我们将至少使用一个 modr/m 字节。那么让我们来看看如何解决这个问题。查看表 2-2。带有 ModR/M 字节的 32 位寻址形式。列代表寄存器操作数,行代表内存操作数。由于我们的寄存器是EDX,我们使用第三列。

内存操作数是[EBX+ECX*4+15h],可以使用 8 位或 32 位位移进行编码。为了获得更短的代码,我们将使用 8 位版本,因此 [--][--]+disp8 行适用。这意味着我们的 modr/m 字节将是 54

我们也需要一个 SIB 字节。这些列在表 2-3 中。带有 SIB 字节的 32 位寻址形式。由于我们的基数是EBX,我们使用第 4 列,[ECX*4] 的行为我们提供了8B 的 SIB 字节。

最后我们添加我们的 8 位位移字节,即15。因此完整的指令是03 54 8B 15。我们可以用汇编器来验证这一点:

2 00000000 03548B15                add edx, [ebx+ecx*4+15h]

【讨论】:

    【解决方案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 from Intel-Doku)
    ------------------------------------------
    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
    

    【讨论】:

      【解决方案3】:

      您正在查看一个操作码映射,该映射在该字节匹配的指令模式中转换操作码的第一个字节。如果你想知道指令的字节rest,你需要看看别处。

      如果您查看 ADD 指令的页面,它会显示如下内容:

      00 /r        ADD r/m8, r8
      

      这告诉您00 字节后跟一个 ModR/M 字节,其中包含寄存器字段中的寄存器 r,并且该寄存器是一个 8 位寄存器,它是 ADD 的第二个操作数指令(指令模式中的r8),而第一个操作数在ModR/M字节的其余部分

      现在,如果您查看 ModR/M 字节的文档,它会告诉您 ModR/M 字节有 3 个字段——一个 2 位“mod”字段,一个 3 位“寄存器/操作码”字段和一个 3 位的“r/m”字段。然后它会给出一个包含所有 256 个 ModR/M 字节值的表格,并注明这些字段在每种情况下的含义。该表(通常)组织为 32 行,每列 8 列 - 32 行分为 4 组,每组 8 组,组对应于“mod”字段位,组内的行对应于“r/m”字段位,而列对应于“寄存器/操作码”字段位。它有点奇怪,因为“mod”是前 2 位,“r/m”是后 3 位,中间是“寄存器/操作码”,但作为“mod”和“r/”是有意义的m' 位密切相关并一起描述一个操作数,而“寄存器/操作码”位几乎完全独立,描述另一个操作数或作为操作码的一部分。

      【讨论】:

        猜你喜欢
        • 2011-08-26
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2012-06-26
        • 2016-10-03
        • 2013-06-19
        • 2010-10-07
        相关资源
        最近更新 更多