The Intel Software Development Manual says this about the neg
instruction:
The CF flag set to 0 if the source operand is 0; otherwise it is set to 1. The OF, SF, ZF, AF, and PF flags are set according to the result.
I thought that AF and CF would be set as if neg %eax
were replaced by,
not %eax # bitwise negation
add $1, %eax
But that's not the case, negating 0x6ffffef5 on a real CPU sets AF and CF.
neg
sets all flags identically to what you'd get with a sub
from 0.
This sequence of instructions sets all flags (including AF and CF) identically to neg %eax
:
xor %ecx, %ecx
sub %eax, %ecx # ecx = 0 - eax
Intel's documentation does actually specify this, but not in the pseudo-code Operation section or in the flags-affected section of the instruction-set reference (Volume 2) entry for neg
itself.
The text of the Description section for neg
includes this nugget:
This operation is equivalent to subtracting the operand from 0.
And in Volume 1:
7.3.2.4 Comparison and Sign Change Instructions
[a paragraph about CMP]
The NEG (negate) instruction subtracts a signed integer operand from zero.
The existence of this documentation was pointed out by a comment on an earlier duplicate of this question which isn't as directly worded.
I didn't know that vol.1 had a whole section explaining the instructions. It turns out that not everything Intel has to say about individual instructions is in the Volume 2 insn set reference.
There's some evidence that neg
decodes internally to the same uop as a sub
instruction on Intel CPUs. (e.g. neg [mem]
can micro-fuse the load with the ALU op, as well as micro-fusing the store-address and store-data uops. inc [mem]
can only micro-fuse the store, so it's 3 total fused-domain uops).