Andrew David (akdavid at ultronics.co.uk), Software Manager, Ultronics Ltd, Cheltenham says:
This division routine uses the standard binary long-division algorithm. The loop iterates once for each bit in the numerator, so it goes round 24 times. For each loop the numerator (sorry, but I can never remember which is the dividend and the divisor - I guess the divisor is the denominator, but I'd hate to get it wrong) is left shifted 1 bit into the remainder, then the remainder is compared with the denominator. If the remainder is greater than the denominator, the denominator is subtracted from the remainder and a 1 is shifted into the quotient, otherwise a 0 is shifted into the quotient. If you can't see how the routine works, try running through an example on paper, in binary, then think about how you'd write the routine.
;============================================================================= ; DIV24_16u ; ; Divides a 24bit number by a 16bit number. Unsigned. ; ; Inputs: ; 24-but numerator in ACCcLO:ACCdHI:ACCdLO ; 16-bit denominator in ACCbHI:ACCbLO ; ; Outputs: ; 24-bit quotient in ACCcLO:ACCdHI:ACCdLO ; 16-bit rem in ACCaHI:ACCaLO ; ; Locals used: ; R5Hi ; ; ; Inputs are not preserved. ; ; No timing analysis performed. ; Andrew David, Software Manager, Ultronics Ltd, Cheltenham ; akdavid at ultronics.co.uk http://www.ultronics.com ; ;============================================================================= DIV24_16u: movlw .24 ; for 24 shifts movwf R5Hi ; clrf ACCaHI,f ; clear remainder. clrf ACCaLO,f ; d2416lp:rlcf ACCdLO,f ; build up remainder. rlcf ACCdHI,f ; rlcf ACCcLO,f ; rlcf ACCaLO,f ; rlcf ACCaHI,f ; ; remainder is 16-bit, but may have spilled over into carry. btfss ALUSTA,C ; check for remainder spill into carry. goto d2416s ; movfp ACCbLO,WREG ; subwfb ACCaLO,f ; Carry bit is the 17th bit of this subtract! movfp ACCbHI,WREG ; subwfb ACCaHI,f ; bsf ALUSTA,C ; bit is known to be zero here. goto d2416ns ; d2416s: movfp ACCbLO,WREG ; Compare remainder with divisor. subwf ACCaLO,w ; movfp ACCbHI,WREG ; subwfb ACCaHI,w ; btfss ALUSTA,C ; goto d2416ns ; (remainder < divisor), shift in a '0' movfp ACCbLO,WREG ; The remainder is larger, so subtract the subwf ACCaLO,f ; ... divisor FROM the remainder and movfp ACCbHI,WREG ; ... shift a '1' into the quot. subwfb ACCaHI,f ; d2416ns:decfsz R5Hi,f ; check all bits goto d2416lp ; rlcf ACCdLO,f ; shift in final quotient bit. rlcf ACCdHI,f ; rlcf ACCcLO,f ; return