2

So, I'm new to assembly programming, as well as the concept of "two's complement" representation of negative numbers, and I'm a little confused.

In the book that I'm reading on the subject of assembly (and on every online resource I've consulted), it is explained that you can tell whether or not a number is negative by looking at its most significant bit; if that bit is 1, it's negative (signed), otherwise, it's positive (unsigned). This doesn't make sense to me, however.

To illustrate my confusion, imagine the unsigned representation of 255: 11111111 That's a positive, unsigned value, but its most significant bit is set. According to the two's complement rules I've been reading about, that should make this number negative rather than positive, but it IS possible to have unsigned values like this with the most significant bit set (if you couldn't do this, an unsigned 8-bit integer could only represent the numbers 0-127). So how does this work? How can I tell if a number is signed or simply unsigned with the most significant bit set? And, possibly more importantly, how can a computer tell the difference? Am I just missing something?

Peter Cordes
  • 328,167
  • 45
  • 605
  • 847
  • Notice how the signed numbers make additional sense together with unsigned math, if you have 255 in 8 bits, and you try to increment it (plus 1), it will overflow the 8 bits and end up as zero (`256` = `1 0000 0000` => 9 bits). This demonstrates 8 bit limit being 255 nicely. But you can look at the same operation in "signed" mode as -1 + 1 = 0. And in the similar way breaking the signed limit: 127 + 1 = -128 (`0111 1111` + 1 = `1000 0000`) -> makes sense in "unsigned" view, as it's 127 + 1 = 128. So the CPU is doing the same add/sub operation for both "signed" and "unsigned" numbers. – Ped7g Sep 29 '16 at 09:35

1 Answers1

3

It is the operation performed on value which defines whether it is signed or unsigned, not the value itself. For example, if you perform mul or div, then the value is treated as unsigned and the most significant bit is the part of the number (thus allowing to perform operation on numbers 0 to 255), but imul or idiv treat the most significant bit as sign (allowing numbers from -128 to 127).

The same for conditional jumps

cmp al, 0x81
jb some_label_1    ; unsigned comparison
jl some_label_2    ; signed comparison
Alexander Zhak
  • 9,140
  • 4
  • 46
  • 72