|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
May 8, 1997 Divide and conquer: binary divisionClive "Max" Maxfield, Intergraph Computer Systems You can carry out binary division, one of the most difficult operations for a computer to perform, in simple mPs using low-level instructions.
So now you know that the first digit of your result is 4 (from the 4×14). Next, you subtract 56 from 66, leaving 10; drop the 3 down to form 103; and go through the process again: 6×14=84, but that's too small; 8×14=112, but that's too big; 7×14=98, and that's as close as you can get. Thus, you now know that the second digit of your result is 7. Finally, you subtract 98 from 103, leaving 5, which is too small to divide by 14, so you know that your result is 47 with a remainder of 5. (Note that you're performing an integer division.) A CPU goes through a similar process; it has to perform a series of iterations by taking stabs in the dark, checking to see if it went too far, and backtracking if it did. To further confuse the issue, you end up doing everything somewhat backward, using the same sort of tricks that you employ to make binary multiplications easier for the CPU to handle (Reference 2).
Whenever the carry flag contains a 1 entering Step 3, the divisor is too big to subtract from the portion of the dividend that you're currently examining. But you discover this information too late, because you've already performed the subtraction, and you now must add the divisor back in. This process is known as a restoring-division algorithm for just this reason; you have to keep on restoring the divisor every time you "go too far." There are nonrestoring-division algorithms, which are somewhat more efficient, but also a tad more complicated--so just ignore them and hope they'll go away.
Commencing with your initial conditions (Figure 4a), you then shift the entire 8-bit result 1 bit to the left and also shift a logic 0 into the least significant bit (Figure 4b). Next, subtract the divisor from the four most significant bits of the result (Figure 4c). However, this step sets the carry flag to a logic 1, which tells you that you've gone too far. Thus, you complete this cycle by adding the divisor back into the four most significant bits of the result (Figure 4d). As fate would have it, the second cycle offers another helping of the same sequence (Figure 5).
When you divide 11 by 3, you expect a quotient (result) of 3 and a remainder of 2. The four most significant bits (which represent the remainder) contain 00102 (2 in decimal), and the four least significant bits (which represent the quotient) contain 00112 (3 in decimal). Good grief, it works! Unfortunately, your division algorithm will not always perform correctly if it encounters negative values, so you have to perform similar tricks to those you used for your signed multiplication subroutines (Reference 2). Thus, you need to check the signs of the numbers first, change any negative values into their positive counterparts using 2's complement techniques, perform the division, and correct the sign of the result if necessary. Now assume that you're working with an 8-bit mP and you wish to create a subroutine to perform signed binary division on 16-bit numbers. Listing 1 (pg 166) describes just such a subroutine, which retrieves two 16-bit signed numbers from the stack, divides one into the other, and places the 16-bit signed result on the top of the stack. (This subroutine assumes that any 16-bit numbers are stored with the most significant byte "on top" of the least significant byte.) Note that the 2-byte remainder from the division ends up in the two most significant bytes of the result (_AH_RES and _AH_RES+1). Thus, if you decide that you want your subroutine to return this remainder, you just add two more pairs of LDA and PUSHA instructions in the _AH_SAVE section of the subroutine (just before you push the return address onto the stack). However, usually you create a separate subroutine that returns just the remainder. Alternatively, you could modify this subroutine to have multiple entry and exit points, depending on whether you wish the subroutine to return the remainder or the quotient. Both techniques save you from passing the remainder back and forth when you don't wish to use it. The assembly language in Listing 1 corresponds to no particular mP; it is designed for the virtual mP implemented in software that accompanies Reference 1
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| EDN Access | Feedback | Table of Contents | |
||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||
| Copyright © 1997 EDN Magazine, EDN Access. EDN is a registered trademark of Reed Properties Inc, used under license. EDN is published by Cahners Publishing Company, a unit of Reed Elsevier Inc. | ||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||||