Skip to content

Instructions

x86-64

NEG

Two's-complement negation — computes 0 minus the operand. Useful for unary minus, absolute value, and as a quick 'is it zero?' carry test.

NEG dst replaces the operand with its two's-complement negation — exactly 0 - dst. It works on a register or memory operand.

asm
mov eax, 5
neg eax           ; eax = -5  (0xFFFFFFFB)
neg eax           ; eax = 5   again

Flags

NEG sets the flags as if it had computed 0 - dst:

  • CF = 0 only when the operand was 0, and 1 otherwise. (Because 0 - 0 produces no borrow, but 0 - anything does.) This makes neg a one-byte "is this value non-zero?" test that drops the answer into CF.
  • ZF, SF, OF, AF, PF are set from the result in the usual way.
  • neg of INT_MIN (0x80000000) yields itself and sets OF — the only value that has no positive counterpart.

Reverse-engineering notes

  • The obvious source mapping is unary minus: -x.
  • Absolute value is often compiled branchlessly as mov tmp, x; sar tmp, 31; xor x, tmp; sub x, tmp rather than with neg — but neg does appear in the simpler pattern test/js … neg. Recognise both.
  • neg then sbb reg, reg (or adc) is an idiom that broadcasts "was it non-zero?" across a whole register (0 → 0, non-zero → all-ones), used to build branchless masks.
  • Don't confuse NEG (arithmetic, 0 - x) with NOT (bitwise complement, ~x). They differ by one: -x == ~x + 1.

See also: Two's complement · AND / OR / NOT · ADC / SBB.

Try it — Virtual CPU

open full playground →
  1. 1 mov eax, 5
  2. 2 neg eax
  3. 3 neg eax
  4. 4
step 0
Loading emulator…