x86 XOR 操作码差异 [英] x86 XOR opcode differences

查看:27
本文介绍了x86 XOR 操作码差异的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

looking at http://ref.x86asm.net/coder32.html I found two opcodes that match for the statement

异或 eax,eax

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

1) opcode 31 XOR r/m16/32 r16/32

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

2) opcode 33 XOR r16/32 r/m16/32

都指的是操作数 1 和操作数 2 的 32 位寄存器.那么,对两个 32 位寄存器进行异或的这种特定情况有什么不同吗?

both refers to 32bit register for operand1 and operand2. So, is there any differences in this specific case of the XORing two 32bit registers ?

推荐答案

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

x86 has 2 redundant ways to encode a 2-register instance of any of the basic ALU instructions (that date back to 8086), using either the r/m source and r/m destination forms.

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

This redundancy for reg,reg encoding is a consequence of how x86 machine code allows a memory-destination or a memory-source for most instructions: instead of spending bits in the ModR/M byte to have a flexible encoding for both operands, there are simply two separate opcodes for most instructions.

(这就是为什么任何指令都不允许使用两个显式内存操作数,例如 xor [eax], [ecx].只有几个指令,其中一个或两个内存操作数是隐式的,例如 rep movspush [mem] 允许两个内存操作数,决不允许一条指令具有两个单独的 ModR/M 编码寻址模式.)

(This is why two explicit memory operands, like xor [eax], [ecx], isn't allowed for any instruction. Only a few instructions where one or both memory operands are implicit, like rep movs or push [mem] allow two memory operands, never one instruction with two separate ModR/M-encoded addressing modes.)

注意 3133 对于 word/dword/qword 大小的 xor 仅在位 #1 上有所不同.其他指令,例如 292B sub 遵循相同的模式.位#1 有时被称为方向";操作码的一部分.(不要与EFLAGS中的DF混淆,方向flag).

Notice that 31 vs. 33 for word/dword/qword-sized xor differ only in bit #1. Other instructions like 29 vs. 2B sub follow the same pattern. Bit #1 is sometimes called the "direction" bit of the opcode. (Not to be confused with DF in EFLAGS, the direction flag).

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

Also note that byte vs. word/dword/qword operand-size versions of those instructions differ only in the low bit, like 30 XOR r/m8, r8 vs. 31 XOR r/m16, r16. Again, this pattern shows up in the ALU instruction encodings that date back to 8086. Bit #0 of those opcodes is sometimes called the "size" bit.

这些基本 ALU"对每个方向和大小组合都有编码的指令可以追溯到原始 8086;许多后来的指令,如 386 bsf r, r/m186 imul r, r/m, imm 没有可以允许内存目的地的形式.或仅用于 bt* r/m, r 目的地可以是 reg/mem.

These "basic ALU" instructions that have an encoding for each direction and size combo date back to original 8086; many later instructions like 386 bsf r, r/m or 186 imul r, r/m, imm don't have a form that could allow a memory destination. Or for bt* r/m, r only the destination can be reg/mem.

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

That's also why later instructions (or new forms of them like imul) usually don't have a separate opcode for byte operand-size, only allowing word/dword/qword via the normal prefix mechanisms. 8086 used up much of the coding space, and later extensions wanted to leave room for more future extensions. So that's why there's no imul r, r/m8.

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

(dword and qword operand size were themselves extensions; 8086 didn't have operand-size or REX prefixes. So original 8086 was fairly sensible in terms of using its opcode coding space, and having patterns to make decoding not a total mess.)

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

For reg,reg instructions, there's no difference in how they decode and execute on any CPUs I'm aware of; the only time you need to care about which encoding your assembler uses is when you want the machine code to meet some other requirement, like using only bytes that represent printable ASCII characters. (e.g. for an exploit payload).

某些汇编器具有覆盖其默认编码选择的语法,例如GAS 有一个 .s 后缀来获取非默认编码.现在已弃用,您应该在助记符之前使用 {load}{store} 前缀(查看文档),如下所示:

Some assemblers have syntax for overriding their default choice of encoding, e.g. GAS had a .s suffix to get the non-default encoding. That's now deprecated, and you should use {load} or {store} prefixes before the mnemonic (see the docs), like so:

{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

(相关:哪些方法可用于在现代 x86 上有效地扩展指令长度? 用于 {vex3}{evex}{disp32 的用例}.)

(Related: What methods can be used to efficiently extend instruction length on modern x86? for use-cases for {vex3}, {evex} and {disp32}.)

NASM 也有 {vex2}{vex3}{evex} 前缀语法为 GAS,例如{vex3} vpaddd xmm1, xmm1, xmm0.但我没有看到一种方法来覆盖 op r/m, rop r, r/m 操作码的选择.

NASM also has {vex2}, {vex3}, and {evex} prefixes with the same syntax as GAS, e.g. {vex3} vpaddd xmm1, xmm1, xmm0. But I don't see a way to override the op r/m, r vs. op r, r/m choice of opcodes.

  • Why does the Solaris assembler generate different machine code than the GNU assembler here? - some assemblers have a different default choice of "direction".
  • Some assemblers have even used that choice (and maybe other redundancies) as a way to footprint / watermark in their output machine code. Notably A86 which was shareware, using this as a way to detect binaries from people that didn't pay the shareware fee. A86 tag wiki.
  • What is the ".s" suffix in x86 instructions? (the precursor to the {load} and {store} overrides in GAS source).
  • Encoding ADC EAX, ECX - 2 different ways to encode? (arch x86)
  • x86 sub instruction opcode confusion

这篇关于x86 XOR 操作码差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆