Our Stupid teacher wants us to implement divison of 32 bits by using 16-bits registers, that means we are not allowed to use EXTENDED registers like EAX...

The question for this particualr prob is:

Assuming u r using an 80286 processor or earlier, write a 32-bit division procedure that works only with 16-bit registers.

Thanx for your help, cuz I have tried everything with no success :(
Posted on 2001-12-01 00:42:56 by ferdoud
Show me the everything you've tried! :)
You can find the source on the web through Google.
Here is the algo I like for the 680x0 processor, though. It's for a 64-bit divide on a 32-bit processor, but you want to do the same thing - read the comments. Please, post your progress. :grin:
ASM_FUNC_HEAD static void Wide_DivideU (

wide *dividend_ptr, /* in/out: 64 bits to be divided */
long divisor, /* in: value to divide by */
long *remainder_ptr) /* out: the remainder of the division */
{
#define DIVIDEND_PTR 8
#define DIVISOR 12
#define REMAINDER_PTR 16

ASM_BEGIN
MOVEM.L D2-D7,-(SP) // save work registers
CLR.L D0 //
CLR.L D1 // D0-D1 is the quotient accumulator
MOVE.L DIVIDEND_PTR(A6),A0 //
MOVE.L WIDE_HI(A0),D2 //
MOVE.L WIDE_LO(A0),D3 // D2-D3 = remainder accumulator
CLR.L D4 //
MOVE.L D2,D5 // D5 = copy of dividend.hi
MOVE.L DIVISOR(A6),D6 // D6 = copy of divisor

MOVEQ.L #31,D7 // FOR number of bits in divisor
@divloop:
LSL.L #1,D0 // shift quotient.hi accum left once
LSL.L #1,D1 // shift quotient.lo accum left once
LSL.L #1,D4 //
LSL.L #1,D3 //
ROXL.L #1,D2 // shift remainder accum left once
SUB.L D6,D2 // remainder -= divisor
BCS @div50 // If CS, remainder is negative
BSET #0,D1 // quotient.lo |= 1
BRA.S @div77 //
@div50:
ADD.L D6,D2 // remainder += divisor
@div77:
BTST D7,D5 //
BEQ @div90 // If EQ, bit not set in dividend.hi
BSET #0,D4 //
@div90:
CMP.L D6,D4 //
BCS @div99 // If CS, divisor < D4
SUB.L D6,D4 // D4 -= divisor
BSET #0,D0 // quotient.hi |= 1
@div99:
DBF D7,@divloop // loop until D7 == -1
MOVE.L DIVIDEND_PTR(A6),A0 // output the remainder
MOVE.L D0,WIDE_HI(A0) //
MOVE.L D1,WIDE_LO(A0) //
MOVE.L REMAINDER_PTR(A6),A0 // output the remainder
MOVE.L D2,(A0) //
MOVEM.L (SP)+,D2-D7 // restore work registers
ASM_END
ASM_FUNC_TAIL
}
The top of the assembly-language loop starts at the @divloop label. For each loop, the algorithm shifts the quotient and the remainder left one bit position before trying to subtract the divisor from the remainder. If the subtraction can be done, the least-significant bit in quotient.lo is set; otherwise, the subtraction is undone by the add instruction near the @div50 label. Then, if the divisor is greater than the loop bits that are accumulating in register D4, the least-significant bit in quotient.hi is set.
Posted on 2001-12-01 00:55:26 by bitRAKE