1

Why does NASM use 0x89 opcode (137) when it assembles a MOV instruction between two registers?

Here is an example of code assembled using NASM:

55      push ebp
89E5    mov ebp, esp
83EC04  sub esp, byte +0x4
31C0    xor eax, eax
C9      leave
C3      ret

I wanted something like this:

55      push ebp
8BEC    mov ebp, esp
83EC04  sub esp, byte +0x4
33C0    xor eax, eax
C9      leave
C3      ret

The reason I wanted 0x8B was: if you view the binary representation of the MOV instruction, it looks like this in NASM:

Opcode     Mod   Reg   R/M
10001001   11    100   101 (89 E5)

The confusing part in this is that the reg operand is the second.

The NASM syntax is this: 0x89 11 source_reg destination_reg
and the MOV instruction is mov destination_reg, source_reg

4

1 回答 1

9

这两个操作码是相同的。这就是 x86 的冗余。汇编器可以选择它喜欢的任何东西

x86 架构的典型指令有两个操作码。其中第一个有一个寄存器作为第一个操作数,一个寄存器或内存位置作为第二个("reg, reg/mem32"在操作码参考或"Gv, Ev"操作码表中缩写)。第二个操作码的操作数是相反的(缩写为"reg/mem32, reg"or "Ev, Gv")。这是有道理的:处理器必须知道它是复制到内存还是从内存中复制。但是当两个操作数都是寄存器时,编码就变得多余了:

                  ; mod reg r/m
03C3 add eax, ebx ;  11 000 011
01D8 add eax, ebx ;  11 011 000

不仅仅是这样的 reg/reg 样式。看这里

不同的汇编器发出不同的操作码,因此该技术可用于识别汇编器

一些汇编器允许您选择编码。例如,如果您附加.s到末尾, GAS 可以发出其他编码

10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh

x86 指令中的“.s”后缀是什么?

于 2013-10-31T01:41:07.560 回答