The Art of Assembly Language
2.5 Signed and Unsigned Numbers
The binary number 0 00000 [3] represents zero, 0 00001 represents one, 0 00010 represents two, and so on towards infinity. But what about negative numbers? To represent signed values, most computer systems use the two's complement numbering system. The representation of signed numbers places some fundamental restrictions on those numbers, so it is important to understand the difference in representation between signed and unsigned numbers in a computer system to use them efficiently .
With n bits we can only represent 2 n different objects. As negative values are objects in their own right, we'll have to divide these 2 n combinations between negative and non-negative values. So, for example, a byte can represent the negative values ˆ’ 128.. ˆ’ 1 and the non-negative values 0..127. With a 16-bit word we can represent signed values in the range ˆ’ 32,768..+32,767. With a 32-bit double word we can represent values in the range ˆ’ 2,147,483,648..+2,147,483,647. In general, with n bits we can represent the signed values in the range ˆ’ 2 n ˆ’ 1 to +2 n ˆ’ 1 ˆ’ 1.
The two's complement system uses the HO bit as a sign bit . If the HO bit is zero, the number is non-negative; if the HO bit is one, the number is negative. Here are some examples using 16-bit numbers:
00 (%1000_0000_0000_0000) is negative because the HO bit is one 0 (%0000_0001_0000_0000) is non-negative because the HO bit is zero FFF (%0111_1111_1111_1111) is non-negative $FFFF (%1111_1111_1111_1111) is negative $FFF (%0000_1111_1111_1111) is non-negative
To negate a two's complement number, you can use the following algorithm:
-
Invert all the bits in the number, that is, change all the zeros to ones and all the ones to zeros.
-
Add one to the inverted result (ignoring any overflow).
For example, these are the steps to compute the 8-bit equivalent of the decimal value ˆ’ 5:
%0000_0101 Five (in binary) %1111_1010 Invert all the bits %1111_1011 Add one to obtain 5 (in two's complement form)
If we take ˆ’ 5 and negate it, the result is 5 (%0000_0101), just as we expect:
%1111_1011 Two's complement for 5 %0000_0100 Invert all the bits %0000_0101 Add one to obtain 5 (in binary)
Here are some 16-bit examples and their negations:
First, negate 32,767 ($7fff):
FFF: %0111_1111_1111_1111 +32,767, the largest 16-bit positive number. %1000_0000_0000_0000 Invert all the bits (8000h) %1000_0000_0000_0001 Add one (8001h or 32,767)
First, negate 16,384 ($4000):
00: %0100_0000_0000_0000 16,384 %1011_1111_1111_1111 Invert all the bits ($BFFF) %1100_0000_0000_0000 Add one ($C000 or 16,384)
And now negate ˆ’ 32,768 ($8000):
00: %1000_0000_0000_0000 32,768, the smallest 16-bit negative number. %0111_1111_1111_1111 Invert all the bits (FFF) %1000_0000_0000_0000 Add one (00 or 32768)
$8000 inverted becomes $7FFF, and after adding one we obtain $8000! Wait, what's going on here? ˆ’ ( ˆ’ 32,768) is ˆ’ 32,768? Of course not. However, the 16-bit two's complement numbering system cannot represent the value +32,768. In general, you cannot negate the smallest negative value in the two's complement numbering system.
[3] The ellipses (' ') have the standard mathematical meaning: repeat a string of zeros an indefinite number of times.
Категории