0
votes

I am having difficulty understanding the overflow flag.

Assume we are working with byte values. I understand that the range is -2^7 to 2^7 - 1 for signed byte values

So if we add decimal 120 with decimal 10 the overflow flag will be set, so will the sign flag, zero flag will be set to 0 and carry flag will also be 0.

This makes sense. However, if we try to overflow negative numbers by subtracting 1 from -127, the overflow flag doesn't set.

I think the problem results in me being confused about how negative numbers are supposed to be added. Can someone help me out with this? Thank you

1
But -127 - 1 doesn't overflow...Oliver Charlesworth
Shouldn't it though? The result should be -128?Jason
-128, indeed. And that's in-range.Oliver Charlesworth
If we subtracting (byte value) 1 - 127 the overflow flag should be set! Check: mov al, 1 sub al, -127GJ.
a signed n-bit data has range from -2^(n-1) to 2^(n-1)-1phuclv

1 Answers

2
votes

Even better lets use 4 bit values. Signed overflow is when the carry in and carry out of the msbit dont match...There is no such thing as an unsigned vs signed addition, the hardware doesnt know. What is signed vs signed is the overflow, carry out which becomes the carry flag is an unsigned overflow. Signed overflow is just called the overflow flag sometimes.

So four bit makes this easier to see, it all scales up the same to as many bit columns as you can tolerate (infinite). So four bits unsigned we can represent the numbers 0 to 15, signed we can go from -8 to +7. If we were to say add the unsigned values 9 + 7 that should give us an unsigned overflow since we cant represent 16.

 1111
  1001
+ 0111
=======
  0000

And it does the result is 0 with a carry out which means signed overflow, but we can use the exact same addition to do a signed add -7 (1001) and + 7 (0111)

 1111
  1001
+ 0111
=======
  0000

which gives us a zero the correct answer, the carry in and carry out of the msbit are both 1 so they match so there is no signed overflow, as we know because we can represent zero in our 4 bit numbering system.

 xy11
  1001
+ 0111
=======
  0000

y is the carry in, x is the carry out.

So we can pick two numbers that go the other way, the signed values -7 + -7 = -14 which we cannot represent with 4 bits

 1001
  1001
+ 1001
=======
  0010

so we get a 2 with a signed overflow. The carry in and carry out of the msbit do not match, so that would assert the overflow flag in your processor status register (for architectures/processors that have an overflow flag). So -127 + (-1)

 11111111
  10000001
+ 11111111
==========
  10000000

-127 - 1 = -128 which is a valid number in an 8 bit signed system. the carry out and carry in of the msbit are both a 1 so the overflow flag will not be set.

Subtraction is as simple. This is the beauty of twos complement, we dont have nor need subtract logic. a - b = a + (-b) and we know that with twos complement to negate a number you "invert and add one". What we do in hardware is feed an add with the second operand inverted and we add one by making the carry in of the lsbit a one. So if we used a subtract operation and did -127 - 1 that means invert the 1 and set the carry in

 111111111   the carry in of the first column is set
  10000001
+ 11111110   1 inverted
==========
  10000000

Subtle but important difference. The carry out bit (msb column) then becomes a borrow, a one means there was no borrow a zero means there was a borrow. The carry in and carry out of the msbit work the same as far as signed overflow goes.