cmpxchg

Compare and exchange

Compares the accumulator (al, ax, eax or rax) with the destination; if equal, stores the source there and sets ZF, else clears ZF and loads the destination into the accumulator.

486 and latertakes lock

Intel's reference: CMPXCHG

CFPFAFZFSFDFOF ●●●●●–●
  • ● set from the result
  • – not changed

Forms

Operands

r/m
A general-purpose register or memory location matching the operation’s size, for example rax or qword [rbp-8]. The byte registers ah, bh, ch and dh cannot be used with a REX prefix, including when the memory address uses r8–r15.
reg
A general-purpose register matching the operation’s size, for example al, ax, eax or rax. The byte registers ah, bh, ch and dh cannot be used with a REX prefix, which is required by spl, bpl, sil, dil and r8–r15.

The accumulator is al, ax, eax or rax, by operand size. On a match it stores the source register into the destination and sets ZF; otherwise it clears ZF and loads the destination's value into the accumulator. The other arithmetic flags are set as cmp would set them for the accumulator and the destination.

The destination can be a register or memory. With a memory destination and a lock prefix the whole compare and store is atomic, which is how a value shared between threads is updated safely: load it into rax, compute the new value in another register such as rbx, then lock cmpxchg [value], rbx. ZF set means the store happened. ZF clear means another thread changed the value first, and rax now holds its new value, ready for another attempt.

global _start

section .text
_start:
        mov rax, 12
        mov rbx, 5
        mov rcx, 3
        mov rsi, 9

        cmpxchg rax, rbx

        mov rax, 60         ; syscall 60: exit
        xor rdi, rdi
        syscall