除法溢出问题

第10章的实验二的问题:这类溢出问题总结起来就是说如果除法的商太大(寄存器溢出),应该如何解决?我在网上各地收集了众家高手的只言片语,如下:

1.如何判断溢出:

如果被除数高位的数值比除数大,那么会产生溢出。比如dx:0010H,ax:2343H,除数cx:0004H,dx>cx,会产生溢出。

2.公式理解:

解决此类溢出王爽的书中提到的公式是 X/N=int(H/N)*65536+[rem(H/N)*65536+L]/N

在汇编中,我们的寄存器是16位的,当我们的除数是16位的时候,我们的除法的被除数就会默认为是32位的,高位在dx中(公式中的H),低位在ax中(公室中的L)。 由于我们在计算过程中,如果被除数过大,而除数过小,比如dx=00ffH,ax=ffffH,而除数为cx=1,这样,我们计算除法的时候,商的值就超出了存放的寄存器的最大值ffffH,溢出了。我们就无法得到正确的商。所以,我们换了一中计算角度,我们把高位和低位分开来进行除法计算,我们先保存ax中的值,然后把dx放入ax中,dx置0,这样,我们进行出发操作,商的值就不会超过FFFFH,不会溢出,我们就能得到dx这个高位数据计算的商和余数,假设商为a,余数为b,但是,我们得到的这个商是用dx计算出来的,dx中的1代表的是1*65536,所以a应该代表的数值是a*65536,而余数b代表的数值应该是b*65536,然后我们再把之前保存的ax中的值放回到ax中,然后加上b*65536H,再次进行除法计算,得到新的商,假设为c和余数x,此时余数x没有什么意义了,因为我们只要的是商。最后,我们就得出了dx=*H,ax=*H,除数为cx=*的商了。(刺猬注:最后的余数x是保存在cx,作者说x没意义,不知为何)


说明:
1.X/N:求x除以N的商
2.int(H/N):高位除以N的商
3.65536:高位和低位的进制
4.rem(H/N):高位除以N的余数
5.rem(H/N)*65536+L:高位和低位相加
6.+[rem(H/N)*65536+L]/N:再次求商
其实我们熟悉的10进制的计算方式,也是符合这个公式的。

3.代码

Divdw:  
        push bx        ;子程序用到的寄存器入栈
        push ax        ;被除数的低16位入栈
         
        mov ax,dx      
        mov dx,0
        div cx         ;先用被除数的高16位除以除数 
        mov bx,ax      ;将int(H/N)存储到bx中,rem(H/N)自动存储到dx 
         
        pop ax         ;被除数的低16位出栈 
        div cx         ;用被除数(rem(H/N)+ax)除以除数
        mov cx,dx      ;将余数存储到cx 
        mov dx,bx      ;将商的高16位存储到dx,商的低16位自动存储到ax 

        pop bx         ;子程序用到的寄存器出栈
        ret 

  • 3
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值