UMBC | CMSC 313 -- Sequential Instructions, Part II | Previous | Next |
In assembly language, both arguments have to be the same size, even when multipling or dividing. Also, when planning, we must consider the worst case as the only case, because the best case will work within the worst case.
So we multiple 8 bits time 8 bits or 16 bits times 16 bits or 32 bits times 32 bits. In assembly language that is the size of the containers. We do not care about the value, just does it fit in the container. When we put a one into a 32 bit container then we are choosing to do a 32 bit multiple. The rule for multiplication is that when multiplying two n-bit containers, the size of the answer 2n.
Multiplication is truly a shortcut for addition, while division is a shortcut for subtraction. Four times three is equal to four plus four plus four. Division is 1) twelve minus four 2) eight minus four and 3) four minus four. Forunately, the hardware designers now let us do it with a single instruction.
However, it is still a little more complex than before. First of all, it takes longer. There is also the problem with the size of numbers (even more so than addition and subtraction!) 99 times 99 is 9801. A byte times a byte can result in a word! Multiplying two n-digit numbers will probably result in a 2n-digit number. Division goes the other direction, but is even more difficult because we have to keep track of the remainder. Then comes the wrinkle of signs!
So when you multiply two sixteen bit numbers, expect the answer to require more bits! The 80x86 CPU requires special registers for this:
Operand Size | Multi- plicand | Multiplier | Product |
---|---|---|---|
BYTE | AL | Reg or Memory | AX |
WORD | AX | Reg or Memory Reg, immed Reg, Reg, immed | AX (low) and DX (high) |
DWORD | EAX | Reg or memory Reg, immed Reg, Reg, immed | EAX (low) and EDX (high) |
Where did this come from???? Well, it starts only with the 386 and works in the 16- or 32-bit mode on signed values only. It is a messy attempt to enhance things. Because of the nature of this mess, it is better not to use it (my opinion!)
Division is similar (except that it does not allow a constant!):
Operand Size | Dividend | Divisor | Quotient | Remainder |
---|---|---|---|---|
BYTE | AX | Reg or Memory | AL | AH |
WORD | AX and DX | Reg or Memory | AX | DX |
You can not use a constant operand with (sometimes )multiplication or (always) division. Use the mov instruction to put a constant into the appropriate register when needed.
Did I mention something about the sign? There are different instructions based on whether or not it is a signed or unsigned operation. That leads us to the following:
Instruction | Description |
---|---|
mul | unsigned multiplication |
div | unsigned division |
imul | signed multiplication |
idiv | signed division |
cwd ; convert the signed word in ax to a double word ; in ax and dx cbw ; convert the signed byte in al to a word in ax cdq ; convert the signed double word in eax to a quad word ; (eight bytes) in edx, eax (higher order is in edx ; ax is unchanged cwde ; convert the signed word in ax to a double word ; in eax
OK, lets put it together:
To do integer division with signed variables (word-sized)of miles driven, divided by number of gallons of gas used, we use C:
short miles; short gallons; short mpg; mpg = miles / gallons;Assembly language requires the programmer to do the dirty work!
mov ax, word [miles] cwd ;ax is assumed idiv word [gallons] ;ax is assumed mov [mpg], ax
To find out how many weeks and days are in a period of days, we could use unsigned bytes and we have two math operations to perform, unsigned division and modulus!
weeks = nrDays / 7; days = nrDays % 7;Interestingly, we only have to do division here, because the remainder is always calculated at the same time, so we just have to save it:
mov al, [nrDays] sub ah, ah ;don't sign extend because that ; could change the value, just ; clear out the high part! mov bl, 7 div bl ;can't use a constant here! mov [weeks], al mov [days], ah ;the remainder is the portion ; of a week
Now an example of multiplication.
; ; One more example, this time with multiplication of a unsigned number ; mov ax, 24 ; there are 24 hours in a day mov bx, 7 ; How many hours in a week? mul bx ; Calculate the answer push eax push string3 call printf