【问题标题】:x86 XOR opcode differencesx86 XOR 操作码差异
【发布时间】:2018-10-24 11:09:40
【问题描述】:

查看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

operand1 和operand2 都是32 位寄存器。那么,在这个对两个 32 位寄存器进行异或的特定情况下有什么不同吗?

【问题讨论】:

  • 两个寄存器没有区别。不同之处在于如果你想要一个内存操作数,第一个是作为目标的内存,第二个是源。
  • 是的,我注意到了,但这对我来说似乎是一个操作码冗余......无论如何不要打扰!

标签: assembly x86 bit-manipulation opcode instruction-encoding


【解决方案1】:

x86 有 2 种冗余方式来编码任何基本 ALU 指令(可追溯到 8086 年)的 2 寄存器实例,使用 r/m 源和 r/m 目标形式。

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

(这就是为什么任何指令都不允许使用两个显式内存操作数,例如 xor [eax], [ecx]。Only a few instructions 其中一个或两个内存操作数是隐式的,例如 rep movs 或 push [mem] 允许两个内存操作数,绝不是一条指令具有两种独立的 ModR/M 编码寻址模式。)


编码有模式

请注意,31 与 33 for word/dword/qword-sized xor 仅在第 1 位不同。其他指令如 29 与 2B sub 遵循相同的模式。 位 #1 有时称为操作码的“方向”位。 (不要与 EFLAGS 中的 DF 混淆,方向 flag)。

还请注意,这些指令的字节与字/双字/qword 操作数大小版本仅在低位上有所不同,例如30 XOR r/m8, r8 与31 XOR r/m16, r16。同样,这种模式出现在可追溯到 8086 的 ALU 指令编码中。这些操作码的位 #0 有时称为“大小”位。

这些具有每个方向和大小组合编码的“基本 ALU”指令可追溯到原始 8086;许多后来的指令(如386 bsf r, r/m 或186 imul r, r/m, imm)没有允许内存目标的形式。或者对于bt* r/m, r 只有,目的地可以是 reg/mem。

这也是为什么后来的指令(或它们的新形式,如 imul)通常没有用于字节操作数大小的单独操作码,只允许通过正常前缀机制的 word/dword/qword。 8086 占用了大部分编码空间,后来的扩展想为更多的未来扩展留出空间。所以这就是为什么没有imul r, r/m8。

(dword 和 qword 操作数大小本身是扩展;8086 没有操作数大小或 REX 前缀。因此,原始 8086 在使用其操作码编码空间方面是相当明智的,并且具有使解码不会一团糟的模式.)


表单之间没有执行差异

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


指定你希望汇编器使用哪种形式

一些汇编器具有覆盖其默认编码选择的语法,例如GAS had a .s suffix to get the non-default encoding。现在已弃用,您应该在助记符 (see the docs) 之前使用 {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

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

(相关:What methods can be used to efficiently extend instruction length on modern x86? 用于 {vex3}、{evex} 和 {disp32} 的用例。)

NASM 也有 {vex2}、{vex3} 和 {evex} 前缀,其语法与 GAS 相同,例如{vex3} vpaddd xmm1, xmm1, xmm0。但我看不到覆盖op r/m, r 与op r, r/m 操作码选择的方法。


相关问答,有些基本重复

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-15
    • 2014-07-29
    • 1970-01-01
    • 2022-11-24
    • 2011-07-05
    相关资源
    最近更新 更多