5710 = 001110012 110 = 000000012 12810 = 100000002 410 = 000001002 12710 = 011111112 25510 = 111111112
Invert +1 Binary 1's Comp 2's Comp -5710 = -001110012 = 11000110 = 11000111 = -5710 -410 = -000001002 = 11111011 = 11111100 = -410 -110 = -000000012 = 11111110 = 11111111 = -110 -12710 = -011111112 = 10000000 = 10000001 = -12710 -12810 = -100000002 -> 01111111 -> 10000000 = -12810 -12910 = -100000012 -> 01111110 -> 10000000 != -12910 -25510 = -111111112 -> 00000000 -> 00000001 != -25510
Range of 16 bit two's complement -216-1 to 216-1-1 or -32768 to 32767 |
00000000 Carry into and out of leftmost 8 bits 110 000000012 bit equal, OF=0. +8 bits +110 = +000000012 8 bits 210 0000000102 Valid unsigned, CF=0. CF = 0 ZF = 0 Valid signed OF=0. OF = 0 SF = 0 |
Unsigned 11111111 Signed Carry into and out of leftmost. 8 bits 25510 111111112 -1 bit equal, OF=0 +8 bits +110 = +000000012 = +1 8 bits 010 1000000002 0 Invalid unsigned, CF=1. CF = 1 ZF = 1 Valid signed, OF=0. Mov Ah, 255 OF = 0 SF = 0 Add Ah, 1 Ah = 0 |
Unsigned 11111111 Signed Carry into and out of leftmost 8 bits 110 000000012 110 bit equal, OF=0. +8 bits +25510 = +111111112 = +(-110) 8 bits 010 1000000002 0 Invalid unsigned, CF = 1. CF = 1 ZF = 1 Valid signed, OF = 0. Mov Ah, 1 OF = 0 SF = 0 Add Ah, 255 OR Ah = 0 Add Ah, -1 |
Unsigned 11111111 Signed Carry into and out of leftmost 8 bits 110 000000012 110 bit equal, OF=0. -8 bits -110 = +111111112 -110 8 bits 010 1000000002 0 Valid unsigned, CF=0 since CF = 0 ZF = 1 inverted on subtraction Mov Ah, 1 OF = 0 SF = 0 Valid signed, OF=0. Sub Ah, 1 Ah = 0 |
Unsigned 01111111 Signed Carry into and out of leftmost 8 bits 12710 011111112 12710 bit equal, OF=0. +8 bits +110 = +000000012 +110 8 bits 12810 0100000002 = -128 Valid unsigned 128, CF=0. CF = 0 ZF = 0 Invalid signed -128, OF=1. Mov Ah, 127 OF = 1 SF = 1 Add Ah, 1 |
Unsigned 10000000 Signed Carry in 0, carry out of leftmost 8 bits 12810 100000002 -12810 bit 1, OF=1. +8 bits +12810 = +100000002 +(-128)10 8 bits 010 1000000002 = 0 Invalid unsigned CF=1. CF = 1 ZF = 1 Invalid signed OF=1. Mov Ah, 128 OF = 1 SF = 0 Add Ah, 128 |
Mov Ah, -1 Neg Ah ;Ah is now +1
Unsigned Signed 255 11111111 127 0111111 +1 = 00000001 +1 = +0000001 0 100000000 -128 01000000 CF=1 Invalid unsigned OF = 1 Invalid signed
Mov Ch, 255 Mov Dh, 127 Inc Ch Inc Dh
9 99 999 11012 *9 *9 *99 *1112 81 891 98901 10110112For 8-bit operands the maximum result is 16-bits in Ax register. Al is always one of the operands in 8-bit multiplication. If the result in Ax requires both the AH and Al registers, OF=1. An example is:
For 16-bit operands the maximum result is 32-bits in DX (high 16-bits) and Ax (low 16-bits). If the result in Dx:Ax requires both the Dx and Ax registers, OF=1. Ax is always one of the operands. An example is:Mov Al, 2 Mov Al, 128 Al Al Mov Bl, 4 Mov Bl, 4 *8-bit operand *4 Mul Bl Mul Bl Ax Ax Ah Al OF Ah Al OF 00 08 0 02 00 1
Mov Ax, 2 Mov Ax, 0FFFFh Ax Ax Mov Bx, 4 Mov Bx, 4 *16-bit operand *4 Mul Bx Mul Bx Dx:Ax Dx:Ax Dx Ax OF Dx Ax OF 0000 0008 0 0002 FFFC 1
Mov Ax, 2 Mov Ax, -2 Ax Ax Mov Bx, -4 Mov Bx, -4 *16-bit operand *-4 IMul Bx IMul Bx Dx:Ax Dx:Ax Dx Ax OF Dx Ax OF FFFF FFF8 0 0000 0008 0
|
Mov Dx, 0 Mov Ax, 23 Mov Ax, 23 Mov Ch, 5 Mov Cx, 5 Div Ch Div Cx Ah Al Dx Ax 03 04 0003 0004 Mov Dx, -1 Mov Ax, -23 Mov Ax, -23 Mov Ch, 5 Mov Cx, -5 Idiv Ch Idiv Cx Ah=-3 Al=-4 Dx=-3 Ax=4 FB FC FFFB 0004 |
+ - - + +/+ +/- -/+ -/- + - + - +4 -4 -4 +4 +5/+23 +5/-23 -5/+23 -5/-23 +3 -3 +3 -3 |
_ Al 8-bit quotient 8-bit divisor/ Ah:Al 16-bit dividend Ah 8-bit remainder
Obviously 52 is wrong! The problem is that Ah=1 was part of the 16-bit dividend in Ax. Ah should have been 0 for unsigned division. A similar problem can occur with signed division, suppose that we attempt -7/5 by:Mov Al, 7 _________ 001101012 = 52 Wrong! Mov Ah, 1 5=000001012/ 00000001 000001112 = 263 Mov Dh, 5 000000112 = 3 Div Dh
Mov Al, -7 _________ 011001012 = 10110 Wrong! Mov Ah, 1 5=000001012/ 00000001 111110012 = 507 Mov Dh, 5 000000102 = 2 Idiv Dh
The 10110 answer is even the wrong sign! What happened? The
problem is that the sign of 8-bit Al needed to be extended into Ah to
correctly convert an 8-bit negative into a 16-bit negative. To see that an 8-bit
signed number can be converted to a 16-bit signed number consider adding more
zeros to the left of any positive number, it is still the same positive number
(e.g. 7=07=007=0007,...). The same is true for negative numbers in two's
complement representation. A 4-bit -1=11112, as 5-bits -1=111112,
as 10-bits -1=11111111112, etc. Converting a signed 8-bit number to a
signed 16-bit number only requires extending the sign of the 8-bit number into
all bits of the 16-bit number. For example, the following produces the
correct results for -7/5.
Mov Al, -7 Al=111110012 Mov Ah, 1 Ah=000000012 Mov Dh, 5 Cbw Ah=111111112 Idiv Dh |
______ Al 111111112 = -1 Correct! 5=000001012/ 11111111 111110012 = -7 Ah 111111102 = -2 |
Mov Al, 255 Mov Ax, 65535 Mov Dh, 10 Mov Bx, 10000 Mov Ah, 0 Mov Dx, 0 Div Dh Div Bx
Mov Al, -7 Mov Ax, -7 Mov Dh, 5 Mov Bx, 5 Cbw Cwd Idiv Dh Idiv Bx
- ReadInt - Inputs a 32-bit signed number from the keyboard and stores into eAx.
Call ReadInt ; cin >> X
Mov X, eAx
- ReadDec- Inputs a 32-bit unsigned number from the keyboard and stores into eAx.
Call ReadDec ; cin >> X
Mov X, Ax
- WriteInt - Outputs a 32-bit signed number from eAx to the screen. Bh=0 to output with no spaces.
Mov eAx, X ; cout << X
Mov Bh, 0
Call WriteInt
- WriteDec - Outputs a 32-bit unsigned number from eAx to the screen. Bh=0 to output with no spaces.
Mov eAx, X ; cout << X
Mov Bh, 0
Call WriteDec- WriteString - Outputs a null-terminated string starting at eDX to the screen.
; cout << Message
mov eDX, offset Message
Call WriteString
- NewLine - Output a new line to the screen.
Call NewLine ; cout << "\n";