What's the difference between cmp and test, and when does a compiler choose each?
cmp A, B sets flags from the subtraction B - A (for comparisons); test A, B sets them from the bitwise AND A & B (for zero/sign/bit tests) — neither stores its result, only the flags.
Both instructions exist purely to set the condition flags for a following jump or setCC, and both throw away the computed value. The difference is the operation:
cmp S2, S1 |
test S2, S1 |
|
|---|---|---|
| Computes | S1 - S2 |
S1 & S2 |
| Typical use | "is B less than / equal to A?" | "is this value zero / negative / is this bit set?" |
| Common idiom | cmp $5, %eax + jl |
test %eax, %eax + je |
When the compiler picks test: to check a value against zero (test %eax, %eax is shorter than cmp $0, %eax), or to test specific bits (test $0x1, %al checks the low bit without a separate mask-and-compare). Because AND doesn't borrow, test never sets CF or OF — only ZF and SF are meaningful after it, which is why you only see je/jne/js/jns after a test.
Gotcha: test %eax, %eax looks like it should "do something" to %eax, but it leaves the register unchanged — its only job is to make ZF and SF reflect the current value.
Go deeper: