昨天看王爽老师的《汇编语言》,卡在第十章“乘法溢出问题“的实验上了。准确的说是卡在书中给出的那个公式上了,今天把代码分步调试了一下,我的疑惑全解开了。
一. 公式:
二. 为了更好的说明这个公式,下面给出 "手动" 版的计算过程 (以书中的 (F4240H / 0AH) 为例)。
1. int(H/N)*65536
即: 000FH / 000AH = 0001H 余 0005H
所以:int(H/N) = 1H , rem(H/N) = 0005H
int(H/N)*65536 = 10000H
2. [rem(H/N)*65536 + L] / N
即: 0005H * 65536 = 50000H
50000H + 4240H = 54240H
所以:[rem(H/N)*65536 + L] / N = 54240H / 0AH = 86A0H 余 0000H
3. 最终结果:
10000H + 86A0H = 186A0H 且余数为0
4. 分析:
由以上三个步骤可以看出:
第一步中:除法的商为最终结果的商的高16位 ( int(H/N)*65536 )。
第二步中:上一步除法的余数(作为高16位)和被除数的低16位(作为低16位)共同参与32位的除法运算,所得的商为最终结果的商的低16位,所得余数为最终结果的余数。
5. 具体子程序:
mov ax,4240H
mov dx,000FH
mov cx,0AH
divdw:push bx
push ax ;将被除数的低16位入栈
mov ax,dx ;将被除数的高16位存入ax
mov dx,0
div cx ;即0000 000FH / 000AH,完成后ax为0001H, dx为0005H
mov bx,ax ;将上面除法结果的商存入bx
pop ax ;将被除数的低16位出栈,存入ax
div cx ;即54240H / 0AH,完成后ax860AH ,dx为0000H
mov cx,dx ;将余数存入cx
mov dx,bx ;将结果的商的高16为存入dx
pop bx
ret
Ps:
1. 网上给出的答案给人的感觉好像是并没有按照这个公式进行计算,但最终的答案是正确的。后来经过在Debug下单步执行,才发现问题所在。
2. 有人说这就是王爽老师没有给这本书配习题解答的原因就是希望读者能够独立思考问题,然后通过一步步的调试最终能写出正确的程序,真是用心良苦啊!