| Opcode | Encoding | 16-bit | 32-bit | 64-bit | Description |
|---|---|---|---|---|---|
38 /rCMP r/m8, r8 | mr | Valid | Valid | Valid | Compare r8 with r/m8. Set the flags and discard the result. |
REX 38 /rCMP 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 /rCMP r/m16, r16 | mr | Valid | Valid | Valid | Compare r16 with r/m16. Set the flags and discard the result. |
39 /rCMP r/m32, r32 | mr | Valid | Valid | Valid | Compare r32 with r/m32. Set the flags and discard the result. |
REX.W 39 /rCMP r/m64, r64 | mr | N/E | N/E | Valid | Compare r64 with r/m64. Set the flags and discard the result. |
3A /rCMP r8, r/m8 | rm | Valid | Valid | Valid | Compare r/m8 with r8. Set the flags and discard the result. |
REX 3A /rCMP 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 /rCMP r16, r/m16 | rm | Valid | Valid | Valid | Compare r/m16 with r16. Set the flags and discard the result. |
3B /rCMP r32, r/m32 | rm | Valid | Valid | Valid | Compare r/m32 with r32. Set the flags and discard the result. |
REX.W 3B /rCMP r64, r/m64 | rm | N/E | N/E | Valid | Compare r/mm648 with r64. Set the flags and discard the result. |
3C ibCMP AL, imm8 | ai | Valid | Valid | Valid | Compare imm8 with AL. Set the flags and discard the result. |
3D iwCMP AX, imm16 | ai | Valid | Valid | Valid | Compare imm16 with AX. Set the flags and discard the result. |
3D idCMP EAX, imm32 | ai | Valid | Valid | Valid | Compare imm32 with EAX. Set the flags and discard the result. |
REX.W 3D idCMP 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 ibCMP r/m8, imm8 | mi | Valid | Valid | Valid | Compare imm8 with r/m8. Set the flags and discard the result. |
REX 80 /7 ibCMP 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 iwCMP r/m16, imm16 | mi | Valid | Valid | Valid | Compare imm16 with r/m16. Set the flags and discard the result. |
81 /7 idCMP r/m32, imm32 | mi | Valid | Valid | Valid | Compare imm32 with r/m32. Set the flags and discard the result. |
REX.W 81 /7 idCMP 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 ibCMP 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 ibCMP 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 ibCMP 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 ibCMP 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
NULLselector. - 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
NULLselector. - 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
SSsegment is in non-canonical form. - If a memory operand using the
SSsegment has an effective address that is outside theSSsegment'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
NULLselector. - 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.