问题描述
问
什么是以下两个x86指令之间的(非平凡)的区别?
What is the (non-trivial) difference between the following two x86 instructions?
39 /r CMP r/m32,r32 Compare r32 with r/m32
3B /r CMP r32,r/m32 Compare r/m32 with r32
背景
我要建一个Java汇编器,这将是我的编译器的中间语言被用来生产Windows的32可执行文件。
I'm building a Java assembler, which will be used by my compiler's intermediate language to produce Windows-32 executables.
目前我有以下code:
Currently I have following code:
final ModelBase mb = new ModelBase(); // create new memory model
mb.addCode(new Compare(Register.ECX, Register.EAX)); // add code
mb.addCode(new Compare(Register.EAX, Register.ECX)); // add code
final FileOutputStream fos = new FileOutputStream(new File("test.exe"));
mb.writeToFile(fos);
fos.close();
要输出一个有效的可执行文件,其中包含在文本部分有两个CMP指令。输出到text.exe会做什么有趣的可执行文件,但是这不是重点。类比较
围绕 CMP
指令的包装。
To output a valid executable file, which contains two CMP instruction in a TEXT-section. The executable outputted to "text.exe" will do nothing interesting, but that's not the point. The class Compare
is a wrapper around the CMP
instruction.
以上code生产(使用OllyDbg的检查):
The above code produces (inspecting with OllyDbg):
Address Hex dump Command
0040101F |. 3BC8 CMP ECX,EAX
00401021 |. 3BC1 CMP EAX,ECX
所不同的是微妙:如果我用 39
字节运算code:
Address Hex dump Command
0040101F |. 39C1 CMP ECX,EAX
00401021 |. 39C8 CMP EAX,ECX
这让我疑惑其同义,为什么这甚至存在。
Which makes me wonder about their synonymity and why this even exists.
推荐答案
这不要紧,如果你比较两个寄存器使用哪种运code。唯一不同的是比较具有存储器的操作数的寄存器时,如运code用于将被减去从中
It doesn't matter which opcode you use if you compare two registers. The only difference is when comparing a register with a memory operand, as the opcode used determines which will be subtracted from which.
至于为什么此存在:x86指令格式使用MODR / M字节表示是存储器地址或寄存器。每条指令只能有一个MODR / M值,这意味着它只能访问一个内存地址(不包括像MOVSB特殊说明)。因此,这意味着不能是一般 CMP R / M32,R / M32
指令,我们需要两个不同的运codeS: CMP R / M32,R32
和 CMP R32,R / M32
。作为一个副作用,比较两个寄存器时会带来一些冗余。
As for why this exists: The x86 instruction format uses the ModR/M byte to denote either a memory address or a register. Each instruction can only have one ModR/M value, which means it can only access one memory address (not including special instructions like MOVSB). So this means that there can't be a general cmp r/m32, r/m32
instruction, and we need two different opcodes: cmp r/m32, r32
and cmp r32, r/m32
. As a side effect, this creates some redundancy when comparing two registers.
这篇关于86 CMP指令差异的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!