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。
一般来说,当被除数的高位,大于等于除数时,就会发生“溢出”。
直接使用 DIV 指令,有一定的风险,一不小心就溢出了。
特别是数字不明确的时候。
因此,在执行 DIV 指令之前,应该加以判断,以免发生溢出。
-----------------------
较好的方法是:编写一个“不会溢出”的除法程序。
方法思路如下:
在右图中,
被除数:1A 2B 3C 4DH,有 32 位数。
除数是:BL,仅有 8 位数。
商,是:32 位数。
按照图中的步骤,需要执行四次 DIV BL。
只要 BL 不为零,就绝对不会发生溢出。
按此思路,被除数的大小,仅仅受制于内模信存的大小。
这就是说:可以认为是无限的。
用 DEBUG 跟踪你的程序,发现,溢出的原因,确实是这条除法指令。
不知道你为什么弄这么大的数字,来除以 3 !
这肯定是会溢出的。
-------------------------------
80x86 CPU 具有两种除法指令:16 位除以 8 位数、32 位除以 16 位数。
它们的商,分别是 8 位和 16 位数。
如果,参加运算的被除数较大,或除数较小,那么,商,就会超出预定的位数。
此时,你贸然使用除法指令,就要溢出了。
由此可知,CPU 自身的指令,有局限性,不要轻易的动用。
-------码兄------------------------
为了避免溢出,执行除法指令之前,应该加以判断:
如果被除数的高位,小于除数,就不会发生“溢出”。
但是,最好,是你自己编写一个“不会溢出的”程序。
编程思路如下:
看懂了让模巧,就会发现,这程序其实也非常简单。
你自己动手编写,一定会成功的。
在图中,被除数是四个字节:1A 2B 3C 4D。
除以 BL 后,得到的商,也是四个字节。
按照图中的步骤,需要执行四次 DIV BL。
只要 BL 不为零,就绝对不会发生溢出。
按此思路,被除数的字节数,可以继续增加,仅受制于内存的大坦键小。
这就是说:被除数,可以认为是无限的。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)