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

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

问题描述

看着 http://ref.x86asm.net/coder32.html 我发现了两个符合该语句的操作码

异或eax,eax

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

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

都指向操作数1和操作数2的32位寄存器.那么,在对两个32位寄存器进行XOR的特定情况下,有什么区别吗?

解决方案

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

这种冗余是x86机器代码如何为大多数指令提供内存目标或内存源的结果:与其在ModR/M字节中花费一些位来为两个操作数提供灵活的编码,不如说是两个大多数指令使用单独的操作码.

(这就是为什么两个显式内存操作数(例如 xor [eax],[ecx] )不允许用于任何指令.只有少数几条指令隐含了一个或两个内存操作数,像 rep movs push [mem] 一样,允许两个内存操作数,一个指令不能具有两个单独的ModR/M编码寻址模式.)


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

某些汇编器具有覆盖其默认编码选择的语法,例如 GAS具有 .s 后缀以获取非默认编码.现在已弃用,您应在助记符之前使用 {load} {store} 前缀(哪些方法可以有效地扩展现代x86上的指令长度?用于 {vex3} {evex} {disp32} .)


NASM还具有与GAS相同语法的 {vex2} {vex3} {evex} 前缀.{vex3} vpaddd xmm1,xmm1,xmm0 .但是我看不到有一种方法可以覆盖 op r/m,r op r,r/m 操作码的选择.

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

xor eax,eax

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

2) opcode 33 XOR r16/32 r/m16/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 has 2 redundant ways to encode a 2-register instance of any of the basic ALU instructions that have r/m source and r/m destination forms.

This redundancy 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.

(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.)


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).

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

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


NASM also has {vex2}, {vex3}, and {evex} prefixes with the same syntax as GAS: {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.

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

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