为什么 NASM 在汇编时使用 0x89 操作码 (137)MOV
两个寄存器之间的指令?
以下是使用 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
两个操作码是相同的。这就是 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 风格。看见here
不同的汇编器发出不同的操作码,因此该技术可用于识别汇编器
一些汇编器允许您选择编码。例如,如果您附加,GAS 可以发出其他编码.s
到最后
10 de adcb %bl,%dh
12 f3 adcb.s %bl,%dh
x86指令中的“.s”后缀是什么?
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)