马上注册,结交更多好友,享用更多功能^_^
您需要 登录 才可以下载或查看,没有账号?立即注册
x
如题。这个程序让我有种久违的数学课的感觉,泪流满面啊:cry
不废话,直接开始,题目中给出了公式:X/N = int(H/N) * 65536 + [rem(H/N) * 65536 + L]/N, 公式里的数字是十进制的,转换成十六进制是: X/N = int(H/N) * 10000h + [rem(H/N) * 10000h + L]/N。先来看下这个公式,公式按+号分为两部分,最终结果 = 第一部分乘以10000H + 第二部分,意思就是int(H/N)的值左移4位,作为最终结果的高位;第二部分作为最终结果的低位,然后把第二部分的余数作为整体计算结果的余数,保存在cx中。具体解题思路如下:
- [b]分析这两部分,都用到了H/N的结果,而且只要H/N的结果计算出来了,那么第一部分的结果就也出来了,因此我们先计算H/N,然后计算第二部分,再计算第一部分,最后再把两部分结果合起来[/b]
- 计算H/N的结果,H: (dx) =000FH,8位;N:(cx)=0AH,8位,计算步骤:(ax)=(dx), div cl。计算结果是(al),余数是(ah)。因为后边还要用到H/N的结果,我们可以在这一步把计算结果保存起来,后续再用到的时候可以直接取值。我看bx还没有用到,就保存到bx里吧。这一步的最终结果是:(bx) = (H/N)。
- [b][rem(H/N) * 10000h + L]/N[/b]。 取H/N的余数,左移4位,加上L之后,除以N,是不是感觉很熟悉?对了,这是个典型的16位除法运算:被除数的高位是rem(H/N),低位是L,除数是N,这就好办了。H/N的结果在bx中,取余数bh放到dx中: (dl) = (bh), (dh) = 0;L原本就在ax中,除数在cx中,所以可以直接除了: div cx。 计算结果商在ax中,余数在dx中。因为这个时候,还有公式第一部分没有计算,但是已经可以确定第一部分的计算用不到cx,因此我们可以按要求,直接把余数放到cx中,这一步的最终结果是:(ax) = [rem(H/N) * 1000h + L]/N 的商,(cx) = [rem(H/N) * 1000h + L]/N的余数,也是最终结果的余数。
- int(H/N) * 1000H。 取H/N的商,左移4位。整个计算的最终结果要求(dx)=结果的高16位,(ax)=结果的低16位,因此,在这里,我们把H/N的商直接保存在dx中就可以了: (dl) = (bl), (dh) = 0。这一步的最终结果是:(dx) = int(H/N)。
- 这时候我们再来回顾整个结果:(dx) = int(H/N) , (ax) = [rem(H/N) * 1000h + L]/N的商, (cx) = [rem(H/N) * 1000h + L]/N的余数,也就是整个结果的余数===>X/N = (dx) = int(H/N) + [rem(H/N) * 1000h + L]/N = (dx) * 10000H + (ax), 余数(cx)
好了,思路已经够详细了,怕麻烦的同学直接看代码(PS: 原题中被除数是0F4240H,除数是0AH,转换成十进制也就是100 0000/10,这样的话,余数是0,不好看,所以我在代码中给改成了100 0001/10,也就是0F4241H/0AH):assume cs:code
code segment
main: mov ax, 4241h
mov dx, 0fh
mov cx, 0ah
call divdw
mov ax, 4c00h
int 21h
divdw: call calch
call calcl
call sum
ret
calch: push ax ; calculate H/N, result --> bx
push cx
mov ax, dx
div cl
mov bx, ax
pop cx
pop ax
ret
calcl: push dx ; [rem(H/N)*10000h + L]/N, quotient-->ax, remainder-->cx
mov dl, bh
mov dh, 0
div cx
mov cx, dx
pop dx
ret
sum: mov dl, bl ; int(H/N) , result --> dx
mov dh, 0
ret
code ends
end main
结果如下:初始状态(ax)=4240H, (dx)=000FH, (cx)=0AH;计算结果:(ax)=86a0H, (dx)=0001H, (cx)=0001H;手动验证一下对不对:
100 0001/10=10 0000 余 1,转化成十六进制:186A0H 余 1,低16位86A0H,高16位0001H,余数0001H, 完全正确:victory::victory::victory:
如果大家有更好的思路,或者更高效的代码,欢迎交流,大家共同学习进步:lol::lol::lol:
|