x86 XOR操作码差异

时间:2018-05-14 17:52:25

标签: assembly x86 bit-manipulation xor opcode

查看http://ref.x86asm.net/coder32.html我找到了两个匹配语句的操作码

xor eax,eax

1)操作码31 XOR r / m16 / 32 r16 / 32

2)操作码33 XOR r16 / 32 r / m16 / 32

两者都指操作数1和操作数2的32位寄存器。那么,XORing两个32位寄存器的具体情况有什么不同吗?

1 个答案:

答案 0 :(得分:5)

x86有2种冗余方式来编码具有r / m源和r / m目标形式的任何基本ALU指令的2寄存器实例。

这种冗余是x86机器代码如何为大多数指令提供内存目的地或内存源的结果:不是花费在ModR / M字节中的位来对两个操作数进行灵活编码,只需要两个大多数指令的单独操作码。

(这就是为什么两个显式内存操作数,如xor [eax], [ecx],不允许任何指令。只有少数指令,其中一个或两个内存操作数是隐式的,如rep movs或{{1允许两个存储器操作数,从不使用两个单独的ModR / M编码寻址模式的指令。)

对于reg,reg指令,它们在我知道的任何CPU上解码和执行的方式没有区别;您需要关心汇编程序使用哪种编码的唯一时间是您希望机器代码满足其他一些要求,例如仅使用表示可打印ASCII字符的字节。 (例如,对于漏洞利用有效载荷)。

某些汇编程序具有覆盖其默认编码选择的语法,例如GAS had a .s suffix to get the non-default encoding。现在已弃用,您应该在助记符(see the docs)之前使用push [mem]{load}前缀,如下所示:

{store}

{load} xor %eax, %ecx {store} xor %eax, %ecx {vex3} vpaddd %xmm0, %xmm1, %xmm1 vpaddd %xmm0, %xmm1, %xmm1 # default is to use 2-byte VEX when possible

gcc -c foo.S && objdump -drwC foo.o

(相关:What methods can be used to efficiently extend instruction length on modern x86?了解0: 31 c1 xor %eax,%ecx 2: 33 c8 xor %eax,%ecx 4: c4 e1 71 fe c8 vpaddd %xmm0,%xmm1,%xmm1 9: c5 f1 fe c8 vpaddd %xmm0,%xmm1,%xmm1 {vex3}{evex}的用例。)

NASM还有{disp32}{vex2}{vex3}前缀,其语法与GAS相同:{evex}。但我没有办法覆盖{vex3} vpaddd xmm1, xmm1, xmm0op r/m, r操作码的选择。