Some basic knowledge of assembly, registers and flags is assumed.

# Unsigned addition

We use an adder circuit in the CPU to do additions. To check for overflows and carry we have 2 flags. Consider we have a 5 bit system. If we do unsigned addition of say, 25 (11001) and 7(00111), the CPU will set the carry flag and the overflow flag to 1 and will set the resultant register value to 0. As the resultant number couldn’t be represented using 5 bits, we set the carry flag to 1. As the number exceeds the unsigned bit range we set the overflow flag it to 1. So here carry flag and the overflow flag represent the same thing!

# How are signed integers represented?

Signed integers are represented differently, as we need 1 extra bit to specify the sign. The simplest way to represent signed integers is by just setting the most significant to the sign bit and represent the unsigned integer in rest of the bits.

Consider an 8 bit environment.

+1 = 00000001 -20 = 10010100 -21 = 10010101

It’s convenient for us, but if you consider making a circuit to compute the result of a signed addition, it gets complicated. We’ll have to check the sign bits and then based on the sign bits we’ll do an addition or a subtraction. That requires us to have a subtractor circuit in our CPU as well.

It turns out we can do better than this if we represent negative numbers as two’s compliment. We still reserve the most significant bit for sign.

1 = 00000001 -21 = 11101011

Let’s now try to add -21 and 1:

111101011 000000001 --------- 111101100 ---------

This gives us: 11101100 (2’s complement = 000010100)

Which is -20 (according to our representation)

The circuit becomes less complicated. We can now do it using just an adder and less comparisons.

# Signed addition

Lets try to add 2 negative integers

-20 = 11101100 -21 = 11101011

11101100 11101011 -------- 11010111 --------

Which is -41. The carry flag will consider the last unsigned addition’s value, it simply asks if there is a carry from the previous addition. Which is yes for this case, so the carry flag is set. Overflow flag checks if the resultant value couldn’t be represented in 8 bits, -41 can be represented and hence the overflow flag is not set in this case.

Now, let’s try to add -121 and -8.

+121 = 01111001 +8 = 00001000 -121 = 10000111 -8 = 11111000

10000111 11111000 -------- 11111111 --------

The resultant value = 11111111. The carry flag will again set to 1. The overflow flag will also set to 1 here as the resultant value = -127 – 8 = -129, can’t be represented in 8 bits (7 + 1 bit for sign).