Instructions
x86-64CMP / TEST
CMP subtracts operands and discards the result to set flags; TEST ANDs them and discards the result — both are the standard way to condition a Jcc.
CMP and TEST exist solely to set EFLAGS for a subsequent conditional jump
or SETcc instruction. Neither writes a result to a register.
CMP
cmp rax, rbx ; EFLAGS ← rax - rbx (result discarded)
cmp rax, 0 ; test for zero/negative
cmp dword [rsp+4], 0x10Sets ZF, CF, SF, OF, PF, AF — identical to SUB but without storing the
difference.
TEST
test rax, rax ; EFLAGS ← rax & rax (result discarded) — idiom for zero/sign check
test rax, 1 ; check bit 0 (LSB) of rax
test al, 0xF0 ; check upper nibble of ALSets ZF, SF, PF; always clears CF and OF — identical to AND but discarding
the result.
Canonical patterns
| Pattern | Meaning |
|---|---|
test rax, rax; je label | jump if rax == 0 (null pointer / false check) |
test rax, rax; js label | jump if rax < 0 (sign check) |
test al, 1; jne label | jump if LSB set (odd / flag check) |
cmp rax, rbx; jl label | jump if rax < rbx (signed) |
cmp rax, 0; je label | redundant with test rax,rax but compiler may emit it |
Reverse-engineering notes
test rax, raxis the most common idiom in compiled code for a null or boolean check. Decompilers render it asif (rax)orif (!rax).- When you see
test eax, eaximmediately after acall, the function's return value (inrax) is being checked for zero/non-zero — a typical error-code test (if (func() == 0)). test al, alafter a string function often checks for a null terminator ('\0').- Because
testclears OF and CF, you can only useje/jne/jssafely after it — usingjlorjbaftertestis unusual and worth flagging.