1

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.

fpmurphy
  • 311
  • 1
  • 2
  • 11

2 Answers2

1

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.

bart1e
  • 3,369
  • 2
  • 8
  • 24
  • 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 04: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 09:09
1
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
blabb
  • 16,376
  • 1
  • 15
  • 30