x86 CMP指令差异

问题描述 投票:13回答:3

问题

以下两条x86指令之间的(非凡的)区别是什么?

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可执行文件。

目前我有以下代码:

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

要输出有效的可执行文件,该文件在TEXT-节中包含两个CMP指令。输出到“ text.exe”的可执行文件不会产生任何有趣的结果,但这不是重点。类CompareCMP指令的包装。

上面的代码产生了(检查OllyDbg):

Address   Hex dump                 Command
0040101F  |.  3BC8                 CMP ECX,EAX
00401021  |.  3BC1                 CMP EAX,ECX

差别是微妙的:如果我使用39字节操作码:

Address   Hex dump                 Command
0040101F  |.  39C1                 CMP ECX,EAX
00401021  |.  39C8                 CMP EAX,ECX

这让我想知道它们的同义性以及为什么甚至存在。

assembly x86 instruction-set cmp
3个回答
19
投票

如果比较两个寄存器,则使用哪个操作码都没有关系。唯一的区别是将寄存器与内存操作数进行比较时,因为所使用的操作码确定将从哪个操作数中减去哪个。

关于其存在的原因:x86指令格式使用ModR / M字节表示存储器地址或寄存器。每条指令只能有一个ModR / M值,这意味着它只能访问一个存储器地址(不包括MOVSB等特殊指令)。因此,这意味着将没有通用的cmp r/m32, r/m32指令,并且我们需要两个不同的操作码:cmp r/m32, r32cmp r32, r/m32。副作用是,在比较两个寄存器时会产生一些冗余。


3
投票

redundancy of x86。有更多这样的情况。编译器/汇编器可以自由使用任何有效的操作码

某些汇编器允许您选择要发出的操作码。例如,在GAS上,您可以附加“ .s”以使用其他指令编码

10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh

1
投票

[CMP ECX,EAXECX-EAXCMP EAX,ECXEAX-ECX。根据将哪个操作数与哪个操作数进行比较,将标志设置为不同。当然,如果不是针对x86指令的mod / r-m结构,那么您可能只能摆脱其中之一。

© www.soinside.com 2019 - 2024. All rights reserved.