| Opcode | Encoding | 16-bit | 32-bit | 64-bit | Description | 
|---|---|---|---|---|---|
| 0F B0 /rCMPXCHG r/m8, r8 | mr | Valid1 | Valid1 | Valid | Compare ALwith r/m8. If equal, setEFLAGS.ZFand move r8 into r/m8. Otherwise, clearEFLAGS.ZFand move r/m8 intoAL. | 
| 0F B0 /rCMPXCHG r/m8*, r8* | mr | N/E | N/E | Valid | Compare ALwith r/m8. If equal, setEFLAGS.ZFand move r8 into r/m8. Otherwise, clearEFLAGS.ZFand move r/m8 intoAL. This uses the alterategpr8encoding. | 
| 0F B1 /rCMPXCHG r/m16, r16 | mr | Valid1 | Valid1 | Valid | Compare AXwith r/m16. If equal, setEFLAGS.ZFand move r16 into r/m16. Otherwise, clearEFLAGS.ZFand move r/m16 intoAX | 
| 0F B1 /rCMPXCHG r/m16, r16 | mr | Valid1 | Valid1 | Valid | Compare EAXwith r/m32. If equal, setEFLAGS.ZFand move r32 into r/m32. Otherwise, clearEFLAGS.ZFand move r/m32 intoEAX | 
| REX.W 0F B1 /rCMPXCHG r/m64, r64 | mr | N/E | N/E | Valid | Compare RAXwith r/m64. If equal, setEFLAGS.ZFand move r64 into r/m64. Otherwise, clearEFLAGS.ZFand move r/m64 intoRAX | 
- This instruction is not supported on processors earlier than the
- 80486
- .
Encoding
| Encoding | Operand 1 | Operand 2 | 
|---|---|---|
| mr | ModRM.r/m[rw] | ModRM.reg[r] | 
Description
The CMPXCHG instruction compares the value in the accumulator with the first ("destination") operand. If the two values are equal, the second ("source") operand is written into the first, and EFLAGS.ZF set. Otherwise, the second operand is loaded into the accumulator and EFLAGS.ZF cleared.
For 64-bit operation in legacy modes, the CMPXCHG8B instruction can be used.
This instruction can be used with the LOCK prefix to allow atomic exectution. To simplify bus operation with locked operation, the destination operand is always written to, even if it is not updated (a locked bus cycle cannot end without a write).
Operation
// if the instruction is LOCKed and `dest` and the accumulator are different, `dest` is reloaded with itself
public void CMPXCHG(ref U8 dest, U8 src)
{
    if (dest == AL)
        dest = src;
    else
        AL = dest;
}
public void CMPXCHG(ref U16 dest, U16 src)
{
    if (dest == AX)
        dest = src;
    else
        AX = dest;
}
public void CMPXCHG(ref U32 dest, U32 src)
{
    if (dest == EAX)
        dest = src;
    else
        EAX = dest;
}
public void CMPXCHG(ref U64 dest, U64 src)
{
    if (dest == RAX)
        dest = src;
    else
        RAX = dest;
}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 if an exchange occurs. Cleared otherwise.
- SF(sign flag)
- Set according to the temporary result.
- OF(overflow flag)
- Set according to the temporary result.
Intrinsics
None. Auto-generated by compiler.
Exceptions
Real-Address Mode
#UD- If the
- LOCK
- prefix is used, but the destination is not a memory operand.
#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, but the destination is not a memory operand.
#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, but the destination is not a memory operand.
#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, but the destination is not a memory operand.
#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, but the destination is not a memory operand.
#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.