Question

I've been trying to get my head around overflow vs carry (for ARM7, but basic enough that I mean the terms as applied to anything).

I think I finally have it - but I want to check that my "real basic understanding" is correct, all complexity removed, is it the case that it really just boils down to:

unsigned => V = 0   
V = 1 => bit n is incorrect
C = 1 => bit n+1 'exists'

Thanks,

Was it helpful?

Solution

These status bits, with respect to overflow, have to do with unsigned vs twos complement.

The addition itself is sign independent, that is the beauty of twos complement. One chunk of logic can be used for unsigned and signed add and subtract. The only place that matters for unsigned vs signed addition or subtraction is the overflow bits, unsigned overflow (a.k.a carry bit) and signed overflow (a.k.a overflow).

The carry bit is hopefully more obvious since we learned about carry in grade school:

   7
  +4
=====

You need to "carry the one" in order to do that addition. Exactly the same in binary except that processors generally have a fixed number of locations, where on paper the width of the operation has to do with how much paper you have.

So for any addition if the carry out of the msbit is set, then there was an unsigned overflow, we didn't have enough bits for the number of columns.

Now this leads to some confusion as the carry bit is talked about for subtraction as well, and this becomes an implementation thing so I wouldn't necessarily (and don't personally) memorize that arm does this, x86 does that, etc. But remember that one way to figure out what a twos complement number is, is "invert and add one". Well when you want to subtract 5 from 7 for example, what you would do in logic, is not add a -5 but instead add the ones complement of 5 and set (invert) the carry in bit:

    1  <- invert or set the carry in bit
  111  <- 7 (0b111)
+ 010  <- ones complement of 5 (0b101)
=====

then we do the math:

 1111  
  111  
+ 010  
=====
  010

and the result is a 2 (2b010) WITH A CARRY OUT?

No that carry out does NOT mean an unsigned overflow. When doing a subtract think of the carry out as inverted from an overflow perspective. Here is where some processors vary. Some will invert the result of the carry flag when the operation is a subtract, so the above ALU operation may result in a carry flag of 1 or a carry flag of 0 for that subtraction depending on the processor which also means when doing a subtract with borrow if the processor supports it, the carry in will invert or not on the way in.

So what about signed overflow?

Well lets look at three bit patterns:

    unsigned signed
000  0       0
001  1       1
010  2       2
011  3       3
100  4      -4
101  5      -3 
110  6      -2
111  7      -1

So for example if we were to add the bit patterns 2b011 + 2b010, unsigned that would be 3+2 = 5, signed that would be 3+2 = -3...ummm, that's wrong. The signed overflow will tell you that. The carry out, unsigned overflow will not be set for that operation, but the signed overflow would be. With x86 there might even be a half overflow and a full overflow? More than one overflow? Somebody has one with the AL, AH and AX stuff..

Anyway

  0100  < - carry in and out
   011
 + 010
======
   100

Notice how the carry in to the msbit is a 1 and the carry out is a 0, that is how we detect that there is a signed overflow.

Yes you can think of it as bit n being wrong because the sign is wrong. It isn't wrong from a math perspective though, bit the sign is wrong because there isn't enough bits to store the answer, no different than an unsigned add of 7+5 = 12 = 0b1100 if we had a 3 bit adder we would get 7+5 = 4 with a carry out indicating there wasn't enough room to store all of the bits of the result. Unsigned overflow.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top