Instructions
x86-64CMOVcc (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, …).
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
| Suffix | Taken when | Typical source |
|---|---|---|
cmove/cmovz | ZF=1 (equal) | a == b ? … |
cmovne/cmovnz | ZF=0 | a != b ? … |
cmovl / cmovge | signed < / >= | signed compare |
cmovb / cmovae | unsigned < / >= | unsigned/pointer |
cmovs / cmovns | sign bit set / clear | sign tests |
Reverse-engineering notes
- A
cmp/testfollowed bycmovccis almost always a compiled ternary (x = c ? a : b) or amin/max/clamp. Reconstruct the source by reading the condition. - Because both arms are evaluated, the compiler only emits
cmovwhen both values are cheap and side-effect-free. Code with side effects in a branch still usesJcc. - 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 ofcmovwhere you'd expect it can be a clue about pointer-safety reasoning. cmovis 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
cmovwith 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 viaxor-zeroing).
See also: Conditional jumps · SETcc · CMP / TEST · RFLAGS.