Intel 的 DIV 指令,是有可能发生【溢出】的。
16 位除以 8 位数,其运算过程是:AX / BL = AL ... AH。
该指令,在 AL 中存放商,在这里,只能存放 8 位数。
那么,当你编程如下:
MOV AX,4000H
MOV BL,1
DIV BL
CPU 执行这三条指令后,溢出,是必然的。
因为,此时的商,还是 4000H,这是 16 位数。
而 DIV 指令,只能存放 8 位数的商。
你一定会看到提示:Divide overflow。
-----------------------
为了解决 DIV 指令溢出的问题,就应该编写一个“多字节的除法程序”。
把商的存放空间,弄大一些。
和被除数一般大,肯定就不会溢出了。
多字节除法的编程思路,可见下图:
图中的被除数,是:1A 2B 3C 4DH,共有 32 位数,够大的吧?
除数,是 BL 中的 8 位数。只要不是 0,就不会溢出。
分四步做除法,即得出“四个字节的商”。
第一次相除,是 8 位数除以 8 位数,肯定不会溢出。
以后每次相除,虽然是 16 位除以 8 位,但是其高 8 位,是上次的余数。
这余数,肯定是小于除数的,所以,商,绝不会超出 8 位。
按此思路做除法,肯定是不会溢出的。
按此思路,被除数的大小,基本上,就可以说:没有限制了。
除数,在 8088 中,可以用 8 位或 16 位。
在 386 以上的 CPU 中,除数还可以用 32 位,这也就足以够用了。
-----------------------
做而论道在图中,仅给出了编程思路,并没有提供程序。
如果,你看图还不能编写出“无溢出”的除法程序,那么,就别弄汇编语言了。
去学 C 语言,就会简单多了。
虽然,C 语言,也有“大数除法”的问题。
不是的,我的被除数放在了DX:AX,除数是16位的dx,却溢出了,被除数有很多,:如16,22,382,1356,16000dd 24486,50065,2759000,3753000 除数有:3,28,220,476,778,4037,5635,8226,11542 这些数进行除法运算,因为这些数字节不统一,我都把它定义成最大字节数的了,方便用LOOP执行
追答上面这些数有些是十进制,有些是16进制吗?请把16进制的加个H再列出来,是做九次除法吗?还是各种组合都要做?
追问上面的DD是我从代码中摘出来没删掉的,都是十进制的数。
这里九个被除数(事实有很多,我只是举例),除数也有九个,让第一个被除数除以第一个除数,第二个被除数除以第二个除数....以此类推。就这样做除法运算。怎么解决溢出问题?谢谢回答!
如果做除法之前DX大于等于CX,这个除法就做不了,加一个判断,出现这种情况如何处理,就看你的具体要求了。
CMP DX,CX
JNC OverFlow
DIV CX
原来的结果处理
OverFlow:
此处加溢出处理
我还是不太明白,你看下代码段源码吧,我到想过用高位和地位分开做除法,就是太麻烦了
;
mov ax,ds:[bx+si+2]
mov es:[bp+7],ax
mov dx,ax ;
mov ax,ds:[bx+si]
mov es:[bp+5],ax ;
div cx ;CX已经定义好了,这些代码放在一个循环中
mov es:[bp+13],ax ;
;
如果你想做正确的除法,需要一个32Bit的单元存放结果,那就可以这样写
mov ax,ds:[bx+si+2]
mov dx,0
div cx
mov es:[bp+13],ax
mov ax,ds:[bx+si]
div cx
mov es:[bp+11],ax
完成了
dword ptr es:[bp+11] = dword ptr ds:[bx+si] / CX
的功能,只要CX不是零,就永远不会溢出了。
听起来有那么点意思,只是CX不为零真的不溢出吗?还有就是DX为零的话,要是AX放不下那么大的数怎么办??
追答DX为零时,AX就不可能放不下得出的商,最坏情况,除之前AX=FFFFH,CX=1,除了以后的商就是FFFFH,还是放得下的。
追问我说的是DX为零,AX放不下被除数时怎么办?我知道商能绝对放得下
追答我上面的例子不就是32位的被除数和16位的除数,实现不溢出的办法吗?
本回答被提问者采纳