为什么nasm在寄存器之间组装MOV指令时使用0x89?

时间:2013-10-19 15:20:07

标签: assembly nasm

为什么NA​​SM在两个寄存器之间组装MOV指令时使用0x89操作码(137)?

以下是使用NASM组装的代码示例:

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

我想要这样的东西:

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

我想要0x8B的原因是:如果你查看MOV指令的二进制表示,它在NASM中看起来像这样:

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

令人困惑的部分是reg操作数是第二个。

NASM语法是:0x89 11 source_reg destination_reg
MOV指令为mov destination_reg, source_reg

1 个答案:

答案 0 :(得分:6)

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

  

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

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

这样的reg / reg风格不仅仅是这样。见here

不同的汇编程序发出不同的操作码,因此该技术可用于identify the assembler

某些汇编程序允许您选择编码。例如,如果您将.s附加到结尾

,GAS可以发出其他编码
10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh

What is the ".s" suffix in x86 instructions?