For an example, we're going to do something very similar to our multiplication example, run backwards. We're going to make a couple of changes:
00110111
. We're going to
use 00111001
, so we get a remainder.
0101
(just like we
multiplied by 0101
last time). But we're going to
0-extend it to eight bits, since we might have to divide by eight
bits.
00001011 ----------------- 00000101 )0000000000111001 00000000 --------------- 0000000000111001 00000000 -------------- 0000000000111001 00000000 ------------- 0000000000111001 00000000 ------------ 0000000000111001 00000101 ----------- 0000000000010001 00000000 ---------- 0000000000010001 00000101 --------- 0000000000000111 00000101 -------- 0000000000000010
Now let's do a table like last time:
Old Result New ---------------------------------------- 0000000000111001 0 0000000000111001 0000000000111001 00 0000000000111001 0000000000111001 000 0000000000111001 0000000000111001 0000 0000000000111001 0000000000111001 00001 0000000000010001 0000000000010001 000010 0000000000010001 0000000000010001 0000101 0000000000000111 0000000000000111 00001011 0000000000000010
Once again, think about just which bits we're considering on each pass:
Old Result New ----------------------------------------------- 000000000 0111001 0 000000000 0111001 0 000000000 111001 0 0 0 000000000 111001 00 000000001 11001 00 0 00 000000001 11001 000 000000011 1001 000 0 000 000000011 1001 0000 000000111 001 0000 1 0000 000000010 001 00000 000000100 01 00001 0 00000 000000100 01 000000 000001000 1 000010 1 000000 000000011 1 0000000 000000111 0000101 1 0000000 000000010
And reformatting to line things up again:
Old Result New ---------------------------------------- 000000000 0111001 0 000000000 0111001 0 000000000 111001 0 0 0 000000000 111001 00 000000001 11001 00 0 00 000000001 11001 000 000000011 1001 000 0 000 000000011 1001 0000 000000111 001 0000 1 0000 000000010 001 00000 000000100 01 00001 0 00000 000000100 01 000000 000001000 1 000010 1 000000 000000011 1 0000000 000000111 0000101 1 0000000 000000010
How does this relate to the HC11? We'll have a 16 bit numerator in
location numerator
. We'll have a 16 bit denominator in
denominator
. We'll end up with our quotient in
x
and our remainder in d
. Here we go:
ldx #0
ldd #0
ldy #16 * loop counter
loop
xgdx * make room in X for next result bit
lsld
xgdx
lsl numer+1 * 32 bit shift! Gets one bit into D
rol numer
rolb
rola
cpd denom * find out if we can subtract on this pass
bcs nosub
subd denom * subtract and put bit into x
inx
nosub dey
bne loop
HC11 has two divide instructions: fdiv
and
idiv
. The distinction is completely unclear from the
pocket guide! It turns out that fdiv
assumes that the
numerator is smaller than the denominator, and computes the fraction -
it does the binary equivalent of calculating that 7/8 = .875 (what it
would get is %1110000
). idiv
does an integer
divide; it computes that 7/8 = 0 with a remainder of 7.
Notice that division is a lot slower than multiplication! This is universally true. Division is just plain harder than multiplication, and so it takes either more time or more hardware to accomplish.