Skip to content

Instructions

x86-64

CMOVcc (conditional move)

Branchless conditional move: copies the source to the destination only when a flag condition holds. The compiler's favourite way to compile a ternary without a jump.

CMOVcc dst, src copies src into dst only if condition cc is true; otherwise dst is left unchanged. It reads the same flags as the conditional jumps and uses the same condition-code suffixes (e, ne, l, ge, a, b, s, …).

asm
cmp eax, ebx
cmovg eax, ebx    ; if eax > ebx, eax = ebx   →   eax = min(eax, ebx)

The whole point is that there is no branch: the instruction always executes and just suppresses the write. That avoids a branch misprediction, which is why compilers reach for it on unpredictable conditions.

Common condition suffixes

SuffixTaken whenTypical source
cmove/cmovzZF=1 (equal)a == b ? …
cmovne/cmovnzZF=0a != b ? …
cmovl / cmovgesigned < / >=signed compare
cmovb / cmovaeunsigned < / >=unsigned/pointer
cmovs / cmovnssign bit set / clearsign tests

Reverse-engineering notes

  • A cmp/test followed by cmovcc is almost always a compiled ternary (x = c ? a : b) or a min/max/clamp. Reconstruct the source by reading the condition.
  • Because both arms are evaluated, the compiler only emits cmov when both values are cheap and side-effect-free. Code with side effects in a branch still uses Jcc.
  • Gotcha — the memory operand is always read. cmovcc reg, [mem] dereferences [mem] regardless of the condition, so the compiler will not use it where the load could fault (e.g. a null-check guarding the very pointer being loaded). Seeing the absence of cmov where you'd expect it can be a clue about pointer-safety reasoning.
  • cmov is also a (weak) constant-time building block: it removes the data-dependent branch. Crypto code sometimes uses it deliberately to avoid timing leaks.
  • There is no cmov with an immediate source — the source must be a register or memory. To select between two constants, the compiler loads them into registers first (often one via xor-zeroing).

See also: Conditional jumps · SETcc · CMP / TEST · RFLAGS.