The difference between cmpl and cmp
Asked Answered
P

3

16

I am trying to understand assembly to be able to solve a puzzle. However I encountered the following instructions:

0x0000000000401136 <+44>:    cmpl   $0x7,0x14(%rsp)
0x000000000040113b <+49>:    ja     0x401230 <phase_3+294>

What I think it's doing is: The value of 0x14(%rsp) is -7380. According to my understanding cmpl compares unsigned. Also the jump is performed.

So can it be that (unsigned)-7380 > 7 --> jump

I actually don't want it to jump. But is this the correct explanation or not? Am I flipping arguments?

Also if you have any advice about how to manipulate this jump!

Prelate answered 9/6, 2014 at 10:43 Comment(4)
l in cmpl is to specify 32-bit memory argument. a part of ja is to specify signed/unsigned. Look up on branch instructions.Deangelo
Probably a good idea to mention (and tag) what processor architecture this refers to.Britannia
it's just the AT&T syntax's size suffixDeaconry
@phuclv: The question isn't specific to x86-64; 32-bit disassembly can also contain cmpl. I re-added the x86 tag (along with AT&T, which this question is specific to. Well I guess goasm syntax for x86 also uses operand-size suffixes...)Enmity
S
25

According to my understanding cmpl compares unsigned.

It does both, in a way.

The difference in signed vs. unsigned is here the usage of the jump instructions.

For >, there is ja for unsigned and jg for signed (jump if above and jump if greater).

For <, there is jb for unsigned and jl for signed (jump if below and jump if less).

To be exact, here is the meaning of several jump commands:

For unsigned comparisons:

JB/JNAE (CF = 1)           : Jump if below/not above or equal
JAE/JNB (CF = 0)           : Jump if above or equal/not below
JBE/JNA (CF = 1 or ZF = 1) : Jump if below or equal/not above
JA/JNBE (CF = 0 and ZF = 0): Jump if above/not below or equal

For signed comparisons:

JL/JNGE (SF <> OF)          : Jump if less/not greater or equal
JGE/JNL (SF = OF)           : Jump if greater or equal/not less
JLE/JNG (ZF = 1 or SF <> OF): Jump if less or equal/not greater
JG/JNLE (ZF = 0 and SF = OF): Jump if greater/not less or equal
Steinbok answered 9/6, 2014 at 11:0 Comment(3)
Above/below are for unsignedClemmie
@Clemmie Thx, added a bit of detailSteinbok
In short: G(reater) and L(ess) are for signed, while A(bove) and B(elow) are for unsigned comparisons.Underthecounter
P
5

Just to add one extra detail for clarification to @glglgl's excellent answer is that the "l" in "cmpl" is an operation suffix indicating that the operation is being done on a long number (32 bit integer or 64-bit floating point).

Pasahow answered 21/1, 2021 at 9:32 Comment(0)
K
-1

I don't think x86 actually has an instruction called CMPL. It's probably part of your assembler syntax to give hints on operands or something else (like JZ and JE being the same).

From the intel manual on what it is doing:

Compares the first source operand with the second source operand and sets the status flags in the EFLAGS register according to the results. The comparison is performed by subtracting the second operand from the first operand and then setting the status flags in the same manner as the SUB instruction. When an immediate value is used as an operand, it is sign-extended to the length of the first operand.

Sign-ness is given implicitly, because of the two's complement representation of numbers.

How to manipulate the jump? If you are sure that the jump should do the exact opposite than what it is doing, you just have to change JA to JBE.

Konstanze answered 9/6, 2014 at 11:13 Comment(2)
That Intel manual quote is misleading: AT&T syntax reverses the order of the operand list.Enmity
@Peter Cordes: Refer to #2398028Against

© 2022 - 2024 — McMap. All rights reserved.