Opcode | Encoding | 16-bit | 32-bit | 64-bit | Description |
---|---|---|---|---|---|
0F C7 mem/1 CMPXCHG8B m64 | m | Valid1 | Valid1 | Valid | Compare EDX:EAX with m64. If equal, set EFLAGS.ZF and move ECX:EBX into m64. Otherwise, clear EFLAGS.ZF and move m64 into EDX:EAX . |
REX.W 0F C7 mem/1 CMPXCHG8B m128 | m | N/E | N/E | Valid | Compare RDX:RAX with m128. If equal, set EFLAGS.ZF and move RCX:RBX into m128. Otherwise, clear EFLAGS.ZF and move m64 into RDX:RAX . |
- This instruction is not supported on processors earlier than the
- Pentium
- .
Encoding
Encoding | Operand |
---|---|
m | ModRM.r/m[rw] |
Description
The CMPXCHG8B
and CMPXCHG16B
instructions compares the value in the data-accumulator register pair with the memory operand. If the two values are equal, the counter-base register pair is written into the operand, and EFLAGS.ZF
set. Otherwise, the second operand is loaded into the accumulator and EFLAGS.ZF
cleared.
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 `addr` and the data-accumulator register pair are different, `addr` is reloaded with itself
public void CMPXCHG8B(ref IntPtr addr)
{
if (Mem32[addr] == EAX && Mem32[addr + 4] == EDX)
{
Mem32[addr] = EBX;
Mem32[addr + 4] = ECX;
}
else
{
EAX = Mem32[addr];
EDX = Mem32[addr + 4];
}
}
public void CMPXCHG16B(ref IntPtr addr)
{
if (Mem64[addr] == RAX && Mem64[addr + 8] == RDX)
{
Mem64[addr] = RBX;
Mem64[addr + 8] = RCX;
}
else
{
RAX = Mem64[addr];
RDX = Mem64[addr + 8];
}
}
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
#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
#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
#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
#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
#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 is not aligned to a 16-byte boundary.
- 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.