Opcode | Encoding | 16-bit | 32-bit | 64-bit | Description |
---|---|---|---|---|---|
38 /r CMP r/m8, r8 | mr | Valid | Valid | Valid | Compare r8 with r/m8. Set the flags and discard the result. |
REX 38 /r CMP r/m8*, r8* | mr | N/E | N/E | Valid | Compare r8 with r/m8. Set the flags and discard the result. This uses the alterate gpr8 encoding. |
39 /r CMP r/m16, r16 | mr | Valid | Valid | Valid | Compare r16 with r/m16. Set the flags and discard the result. |
39 /r CMP r/m32, r32 | mr | Valid | Valid | Valid | Compare r32 with r/m32. Set the flags and discard the result. |
REX.W 39 /r CMP r/m64, r64 | mr | N/E | N/E | Valid | Compare r64 with r/m64. Set the flags and discard the result. |
3A /r CMP r8, r/m8 | rm | Valid | Valid | Valid | Compare r/m8 with r8. Set the flags and discard the result. |
REX 3A /r CMP r8*, r/m8* | rm | N/E | N/E | Valid | Compare r/m8 with r8. Set the flags and discard the result. This uses the alterate gpr8 encoding. |
3B /r CMP r16, r/m16 | rm | Valid | Valid | Valid | Compare r/m16 with r16. Set the flags and discard the result. |
3B /r CMP r32, r/m32 | rm | Valid | Valid | Valid | Compare r/m32 with r32. Set the flags and discard the result. |
REX.W 3B /r CMP r64, r/m64 | rm | N/E | N/E | Valid | Compare r/mm648 with r64. Set the flags and discard the result. |
3C ib CMP AL, imm8 | ai | Valid | Valid | Valid | Compare imm8 with AL . Set the flags and discard the result. |
3D iw CMP AX, imm16 | ai | Valid | Valid | Valid | Compare imm16 with AX . Set the flags and discard the result. |
3D id CMP EAX, imm32 | ai | Valid | Valid | Valid | Compare imm32 with EAX . Set the flags and discard the result. |
REX.W 3D id CMP RAX, imm32 | ai | N/E | N/E | Valid | Compare imm32 (sign extended to 64 bits) with RAX . Set the flags and discard the result. |
80 /7 ib CMP r/m8, imm8 | mi | Valid | Valid | Valid | Compare imm8 with r/m8. Set the flags and discard the result. |
REX 80 /7 ib CMP r/m8*, imm8* | mi | Valid | Valid | Valid | Compare imm8 with r/m8. Set the flags and discard the result. This uses the alterate gpr8 encoding. |
81 /7 iw CMP r/m16, imm16 | mi | Valid | Valid | Valid | Compare imm16 with r/m16. Set the flags and discard the result. |
81 /7 id CMP r/m32, imm32 | mi | Valid | Valid | Valid | Compare imm32 with r/m32. Set the flags and discard the result. |
REX.W 81 /7 id CMP r/m64, imm32 | mi | N/E | N/E | Valid | Compare imm32 (sign extended to 64 bits) with r/m64. Set the flags and discard the result. |
82 /7 ib CMP r/m8, imm8 | mi | Valid | Valid | Invalid | Compare imm8 (sign extended to 8 bits) with r/m8. Set the flags and discard the result. Undocumented. |
83 /7 ib CMP r/m16, imm8 | mi | Valid | Valid | Valid | Compare imm8 (sign extended to 16 bits) with r/m16. Set the flags and discard the result. |
83 /7 ib CMP r/m32, imm8 | mi | Valid | Valid | Valid | Compare imm8 (sign extended to 32 bits) with r/m32. Set the flags and discard the result. |
REX.W 83 /7 ib CMP r/m64, imm8 | mi | N/E | N/E | Valid | Compare imm8 (sign extended to 64 bits) with r/m64. Set the flags and discard the result. |
Encoding
Encoding | Operand 1 | Operand 2 |
---|---|---|
mr | ModRM.r/m[r] | ModRM.reg[r] |
rm | ModRM.reg[r] | ModRM.r/m[r] |
ai | AL/AX/EAX/RAX | imm8/16/32 |
mi | ModRM.r/m[r] | imm8/16/32 |
Description
The CMP
instruction subtracts the second source operand from the first. The flags are updated and the result discarded.
This instruction internally operates the same as SUB
, but without writing the result back. As such, the CMP
instruction is the only one of the eight original ALU instructions that cannot be used with the LOCK
prefix.
Operation
// `src2` is sign extended to the width of `src1`
public void CMP(ref U8 src1, U8 src2)
{
_ = src1 - src2;
}
public void CMP(ref U16 src1, U16 src2)
{
_ = src1 - src2;
}
public void CMP(ref U32 src1, U32 src2)
{
_ = src1 - src2;
}
public void ADD(ref U64 src1, U64 src2)
{
_ = src1 - src2;
}
Flags Affected
CF
(carry flag)- Set according to the temporary result.
PF
(parity flag)- Set according to the temporary result.
AF
(auxiliary flag)- Set according to the temporary result.
ZF
(zero flag)- Set according to the temporary result.
SF
(sign flag)- Set according to the temporary result.
OF
(overflow flag)- Set according to the temporary result.
Exceptions
Real-Address Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If a memory operand using the
SS
- segment has an effective address that is outside the
SS
- segment's limit.
#GP(0)
- If a memory operand (using a segment other than
SS
- ) has an effective address that is outside the segment's limit.
Virtual-8086 Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If a memory operand using the
SS
- segment has an effective address that is outside the
SS
- segment's limit.
#GP(0)
- If a memory operand (using a segment other than
SS
- ) has an effective address that is outside the segment's limit.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Protected Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If a memory operand using the
SS
- segment has an effective address that is outside the
SS
- segment's limit.
#GP(0)
- If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULL
selector. - If a memory operand (using a segment other than
SS
) has an effective address that is outside the segment's limit.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Compatibility Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If a memory operand using the
SS
- segment has an effective address that is outside the
SS
- segment's limit.
#GP(0)
- If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULL
selector. - If a memory operand (using a segment other than
SS
) has an effective address that is outside the segment's limit.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.
Long Mode
#UD
- If the
LOCK
- prefix is used.
#SS(0)
- If a memory operand using the
SS
segment is in non-canonical form. - If a memory operand using the
SS
segment has an effective address that is outside theSS
segment's limit.
#GP(0)
- If a memory operand (using a segment other than
SS
) is in non-canonical form. - If the destination is located in a non-writable segment.
- If a memory operand uses a segment containing a
NULL
selector. - If a memory operand (using a segment other than
SS
) has an effective address that is outside the segment's limit.
#PF(fc)
- If a page fault occurs.
#AC(0)
- If alignment checking is enabled while the current privilege level is 3 and an unaligned memory access is made.