Search code examples
assemblyx86cpu-registerseflagssigned-overflow

Why is the overflow flag not being set in this example?


mov     al, -1
add     al, 130

I am attempting to answer a question from the textbook for my x86-assembly class. One of the examples asks to explain why the over flag would help you determine if, in this instance, the final value of al falls within a valid signed range.

My initial thoughts were that the Overflow flag should be called, since -1 + 130 = 129, which is outside the range of a signed 8-bit integer, with al being the lowest 8 bits of the EAX register. But when I run this code in Visual Studio, I don't see the Overflow flag ever being set.


Solution

  • 130 cannot be represented in 8 bits signed, as 127 is the max signed 8-bit number.  130 in a hex byte is 82h and taken as a signed byte, that is also -126.

    The assembler is not complaining, so I take it that it assumes your intent is unsigned, which can represent 130 in 8 bits.

    Overflow flag tells us about going out of bounds for signed arithmetic, and you're adding -1 to -126, which does not overflow.

    The carry flag is the out of bounds indicator for for unsigned arithmetic (and I would expect that to be set as 130+255 is out of bounds).


    Due to using 2's complement arithmetic the bit pattern of the answer is the same for signed vs. unsigned addition, so instruction sets will generally only have one add operation — but the check for out of bounds is different for signed arithmetic vs. unsigned arithmetic.


    There is no good standard for mixing unsigned and signed arithmetic in the same number of bits, so what we usually do is to expand both operands to larger number of bits, signed to accommodate both operands accurately, and use that form for the arithmetic.