Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

x86 CMP Instruction Difference

Question

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

Background

I'm building a Java assembler, which will be used by my compiler's intermediate language to produce Windows-32 executables.

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

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.

The above code produces (inspecting with OllyDbg):

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

The difference is subtle: if I use the 39 byte-opcode:

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.

like image 622
Pindatjuh Avatar asked May 03 '10 19:05

Pindatjuh


People also ask

What does CMP mean in x86?

The CMP instruction compares two operands. It is generally used in conditional execution. This instruction basically subtracts one operand from the other for comparing whether the operands are equal or not. It does not disturb the destination or source operands.

What is difference between CMP and test instruction?

The TEST instruction performs an implied AND operation between corresponding bits in the two operands and sets the flags without modifying either operand. reg, mem, and immed can be 8, 16, or 32 bits. The CMP instruction sets the flags as if it had performed subtraction on the operand.

How does CMP instruction work?

The CMP instruction subtracts the value of Operand2 from the value in Rn . This is the same as a SUBS instruction, except that the result is discarded. The CMN instruction adds the value of Operand2 to the value in Rn . This is the same as an ADDS instruction, except that the result is discarded.

What does CMP stand for in assembly language?

Compare Two Operands (cmp) (IA-32 Assembly Language Reference Manual)


2 Answers

It's redundancy of x86. There are much more many cases like this. A compiler/assembler is free to use any of the valid opcodes

Some assembler allows you to choose which opcode to emit. For example on GAS you can attach ".s" to use the other instruction encoding

10 de   adcb   %bl,%dh
12 f3   adcb.s %bl,%dh
like image 32
phuclv Avatar answered Oct 17 '22 09:10

phuclv


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.

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.

like image 66
interjay Avatar answered Oct 17 '22 10:10

interjay