汇编语言中的除法溢出,请高手帮忙解决

供稿:hz-xin.com     日期:2025-01-12
关于汇编中除法溢出问题?

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 语言,也有“大数除法”的问题。

CPU 执行除法指令 DIV CX、DIV BL,是有可能溢出的。
特别是除数为零时,必然会出现:Divide overflow。
此外,当被除数的高位,大于等于除数时,也会发生“溢出”。
你问:“如果[rem(H/N)*65536 + L]/N的结果,商大于65535,那不是照样溢出?”
你这问题,是不成立的。
“余数 * 65536 ”中的“余数”,就是高八位,它是小于除数的。
那么“余数 * 65536 + L”再除以除数,得到的商,就不会大于 65535。
-----------------------
一般来说,在执行 DIV 指令之前,应该加以判断,以避免溢出。
较好的方法是:编写一个“不会溢出”的除法程序。
方法思路如下:

在右图中,
被除数是:1A2B3C4DH,有 32 位数。
除数是:BL,仅有 8 位数。
商,是:32 位数。
按照图中的步骤,只要 BL 不为零,就绝对不会发生溢出。

用 DEBUG 跟踪你的程序,发现,溢出的原因,确实是这条除法指令。

不知道你为什么弄这么大的数字,来除以 3 !

这肯定是会溢出的。

-------------------------------

80x86 CPU 具有两种除法指令:16 位除以 8 位数、32 位除以 16 位数。

它们的商,分别是 8 位和 16 位数。

如果,参加运算的被除数较大,或除数较小,那么,商,就会超出预定的位数。

此时,你贸然使用除法指令,就要溢出了。

由此可知,CPU 自身的指令,有局限性,不要轻易的动用。
-------------------------------
为了避免溢出,执行除法指令之前,应该加以判断:

如果被除数的高位,小于除数,就不会发生“溢出”。

但是,最好,是你自己编写一个“不会溢出的”程序。

编程思路如下:

看懂了,就会发现,这程序其实也非常简单。

你自己动手编写,一定会成功的。

在图中,被除数是四个字节:1A 2B 3C 4D。

除以 BL 后,得到的商,也是四个字节。

按照图中的步骤,需要执行四次 DIV  BL。

只要 BL 不为零,就绝对不会发生溢出。

按此思路,被除数的字节数,可以继续增加,仅受制于内存的大小。

这就是说:被除数,可以认为是无限的。



楼主提完问题就不管了

这个问题已经有人提过,请参见下方的参考资料。

汇编语言中的除法溢出,请高手帮忙解决
80x86 CPU 具有两种除法指令:16 位除以 8 位数、32 位除以 16 位数。它们的商,分别是 8 位和 16 位数。如果,参加运算的被除数较大,或除数较小,那么,商,就会超出预定的位数。此时,你贸然使用除法指令,就要溢出了。由此可知,CPU 自身的指令,有局限性,不要轻易的动用。---为了避免溢...

VB编写一个简单的公式,产生数据溢出,请高手帮忙。感谢。
e1 = ( (1 - c1) - d1) \/ (1 - c1),然后再拆开就成了 e1=1 - d1 \/ (1-c1),即使这里c1输入1,那么错误也是除数为零而不是溢出……

...语言 32位*32位 二进制数怎么做乘法??高手帮忙啊~
data4 dw ?data3 dw ?data2 dw ?data1 dw ?2、以下是加、减、乘、除的4个子程序 ;;32位运算 ;;=== ;32位符号数的加法运算 ;入: DXAX=32位操作数1 ; CXBX=32位操作数2 ;出: DXAX=两操作数的和 ; OF=1: 溢出 ; OF=0: 正常 ;=== subn_add32 proc near add ax,bx adc...