# How is subtraction performed on unsigned numbers within the CPU?

I am learning about various flag states for the cmp instruction. From reading, the cmp instruction is really just a sub instruction that sets the various flags (OF, CF, ZF) accordingly depending on the result of the sub.

As I understand it, there is no pure "subtraction (sub)" instruction implementation in x86, rather, the second operand is negated, and then the two numbers are added; i.e. 8-4 becomes 8+(-4).

If this is true, then how is subtraction implemented for unsigned numbers? For example, if we are limited to 8 bits and want to subtract 255-254, the 2's compliment representation of 254 is well outside of the range of 8 bits.

Signed and unsigned numbers are added / subtracted in exactly the same way (add / sub will set both `OF` and `CF` flag). The only difference is how you interpret the result. See link and link.

When you subtract two `8` bit numbers, say `a - b`, it's like you were adding `256 - b = 0b11111111 - b + 1 = NOT(b) + 1` to `a`. In case of `a = 255`, `b = 254`, `a - b = 255 + NOT(0b11111110) + 1`.

For any `8` bit number `n`: `n + NOT(n) + 1 = 0`, so `NOT(n) + 1` is the inverse of `n` (in additive group) modulo `256` no matter if you interpret it as signed or unsigned.

• Ok. So I guess you negate the number by simply taking the 2's compliment of it, minus the MSB sign bit (which isn't relevant for addition anyway) and then add as normal – MisterMister Sep 18 '19 at 4:06
• Yes. First, you negate the number you want to subtract by changing all 1s to 0s and vice versa and then add 1 to it. Then the addition is performed. – bart1e Sep 18 '19 at 9:09
``````a = 255
b = 254
c = int(bin(~b),2)
print ("subtracting is equal to not (input) + 1")
print ("254 = 0b11111110  flipped 254= 0b00000001 adding one makes it 0n00000010")
print ("adding 0b11111111 to 0b00000010 will leave 0b00000001 ")
print ("a =", a , "b =" , b , "not b =", c , "a+b =", a+c , "final result =" , a+c+1 )
``````

result

``````:\>python sub.py
subtracting is equal to not (input) + 1
254 = 0b11111110  flipped 254= 0b00000001 adding one makes it 0n00000010
adding 0b11111111 to 0b00000010 will leave 0b00000001
a = 255 b = 254 not b = -255 a+b = 0 final result = 1
``````