Not understanding FLAGS status register

Multi tool use
Not understanding FLAGS status register
I was helping a friend of mine doing some computer architechture theory exercises. We stumbled on this m.c. exercise about the FLAGS register and don't really know how to answer it. It goes on something like this:
"Assume that you've performed an ADD operation between two unsigned integer numbers, and that it resulted in the following flags setting: CF = 0; OF = 1; ZF=0; SF=1 . What can we conclude from this setting and why?"
The correct choice states that the result of that operation is correct, and when saying why, it states " because the CF equals zero". My question here is why do we only need to consider the carry flag when there are other flags set to one? And also, how is possible for the overflow and the signed flag to be set to one when we are performing an add operation between to unsigned integers?
Thanks in advance!
2 Answers
2
The Carry flag reflects the generation of a carry from the most significant bits of the operation. For unsigned operands, such a carry would reflect an overflow.
As for the other flags, the Sign flag is only applicable for signed operands. The same is true for the Overflow flag since it is set when the sign changes incorrectly due to overflow of a signed operation.
The final flag, Zero, is set when the result is zero and has no relevance for overflow detect.
In the example you present, the operands are unsigned and the Carry flag is cleared. So no overflow has occurred.
The signedness of the operands is a matter of interpretation. Almost no processors have separate signed and unsigned versions of the instructions. It's all a matter of how the results are used that matter. So indeed a single instruction could have set all those bits. For example (using 8 bits for brevity) 0x7F + 0x01 would have a result of 0x80. This would result in the flag values you specified. No carry, sign bit set, signed overflow, not zero.
– Peter Camilleri
Jul 2 at 3:45
Understood! Thank you so much.
– NGSBNC
Jul 2 at 22:33
CF=0 tells you the ADD didn't wrap. See this article on Understanding Carry vs. Overflow conditions/flags .
You could say ADD always gives the correct (a + b) modulo 2^32
result, unless your computer is broken. If the ADD wrapped around, the result isn't the same as the infinite-precision mathematical sum of the two inputs, but it is correct modulo arithmetic (doing the modulus operation for free). So you have to be careful what you mean by "correct"! (Clearly in this case your assignment means the mathematical integer sum.)
(a + b) modulo 2^32
Terminology is confusing here, because "arithmetic overflow" as a general concept (when the mathematically exact result can't fit in the destination) includes the signed and unsigned integer cases. On x86 (like all normal CPUs), the behaviour is wraparound. But unsigned wraparound is called carry, while signed wraparound is called overflow.
With floating point, the normal overflow behaviour is saturation to +/-Infinity. This illustrates the difference between overflow as a general concept and wraparound as the specific behaviour of integer overflow.
Some architectures have a saturating-add instruction with saturation as the integer overflow behaviour. x86 has the paddusw
instruction (and a signed version) for integer SIMD, but not for scalar GP registers like EAX.
paddusw
In C, unsigned overflow is defined to wrap around, but signed overflow is undefined behaviour (and compilers can optimize on the assumption it doesn't happen).
MIPS has an add
instruction that traps on signed overflow. (C compilers typically use addu
for everything, though, because MIPS is a 2's complement machine so its the same binary operation, just different trapping behaviour. They could only safely use add
to trap signed-overflow UB when the things they were adding matched variable values that would occur in the C abstract machine, not after optimization. And some bithack code unsafely relies on signed-wraparound in C, so users normally want wrapping instead of trapping. MIPS doesn't have a FLAGS register of any kind, so that's how they decided to provide hardware support for overflow-checked addition.)
add
addu
add
Some of this is rarely / never useful, but here's my answer to "what can you conclude?".
ZF=0 tells you that the result is non-zero. If you were implementing something like if (a + b != 0)
, you could branch (or cmov or setcc) on the flags set by ADD instead of doing a separate test eax,eax
. It's not at all rare to use ZF after instructions other than cmp or test.
if (a + b != 0)
test eax,eax
SF=1 tells you the result is >= half the maximum value. i.e. that the unsigned result has its high bit set. For an 8-bit ADD, SF=1 means the result is >= 128.
This can sometimes save you a test or compare instruction. If you're adding a register to itself as a left-shift, then CF has the bit shifted out and SF has the current high bit. I guess OF tells you something about
OF=1 (with SF=1 and CF=0) tells you that both inputs were smaller than half the maximum unsigned value. (i.e. if interpreted as signed numbers, they were positive. The signed interpretation of the result is negative, so the signed interpretation of the result is pos + pos = neg, which can only happen via overflow).
I've never taken advantage of that last one in any asm I've written, and it seems unlikely it would be useful. No architecture I'm aware of has any branch conditions that look at both CF and OF. So it would only be useful if you were already in a CF=0 branch. x86 has signed greater / less branches that check SF != OF, but you still can't check SF==1 and OF==1 with a single instruction. So probably if you wanted to check that condition, you'd OR
the two inputs and check SF of that.
OR
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
So if I'm getting it right, those flags being set to one could be the result of previous operations involving signed operands and not the operation described above? Thank you!
– NGSBNC
Jul 1 at 20:47