Pin*_*juh 13 x86 assembly instruction-set cmp
题
以下两个x86指令之间的(非平凡)差异是什么?
39 /r CMP r/m32,r32 Compare r32 with r/m32
3B /r CMP r32,r/m32 Compare r/m32 with r32
Run Code Online (Sandbox Code Playgroud)
背景
我正在构建一个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();
Run Code Online (Sandbox Code Playgroud)
输出有效的可执行文件,其中包含TEXT部分中的两条CMP指令.输出到"text.exe"的可执行文件不会有任何意义,但这不是重点.该类Compare是CMP指令的包装器.
上面的代码生成(使用OllyDbg检查):
Address Hex dump Command
0040101F |. 3BC8 CMP ECX,EAX
00401021 |. 3BC1 CMP EAX,ECX
Run Code Online (Sandbox Code Playgroud)
差别很小:如果我使用39字节操作码:
Address Hex dump Command
0040101F |. 39C1 CMP ECX,EAX
00401021 |. 39C8 CMP EAX,ECX
Run Code Online (Sandbox Code Playgroud)
这使我怀疑他们的同义词以及为什么会存在这种同义词.
int*_*jay 19
如果比较两个寄存器,使用哪个操作码无关紧要.唯一的区别在于将寄存器与存储器操作数进行比较,因为所使用的操作码确定将从哪个操作数中减去哪个.
至于为什么存在:x86指令格式使用ModR/M字节来表示存储器地址或寄存器.每条指令只能有一个ModR/M值,这意味着它只能访问一个存储器地址(不包括MOVSB等特殊指令).所以这意味着不能有一般cmp r/m32, r/m32指令,我们需要两个不同的操作码:cmp r/m32, r32和cmp r32, r/m32.作为副作用,这在比较两个寄存器时会产生一些冗余.
它是 x86的冗余。像这样的案例还有很多。编译器/汇编器可以自由使用任何有效的操作码
某些汇编程序允许您选择要发出的操作码。例如在 GAS 上,您可以附加“.s”以使用其他指令编码
10 de adcb %bl,%dh
12 f3 adcb.s %bl,%dh
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6948 次 |
| 最近记录: |