下载此文档

入党积极分子培训.ppt


文档分类:办公文档 | 页数:约29页 举报非法文档有奖
1/29
下载提示
  • 1.该资料是网友上传的,本站提供全文预览,预览什么样,下载就什么样。
  • 2.下载该文档所得收入归上传者、原创者。
  • 3.下载的文档,不会出现我们的网址水印。
1/29 下载此文档
文档列表 文档介绍
8086汇编中编写无溢出除法的子程序
一、为什么除法会溢出
看到这个标题,你可能会问汇编中不是有div指令来实现除法运算吗?为什么我们还要自己写一个子程序来实现除法?为了说明我们为什么需要自己写一个实现除法的子程序,还得从除法为什么会发生溢出说起。
在汇编中,如果要使用除法运算,我们可以使用div指令,它实现的就是除法的功能,但是它是一个非常容易,甚至说不可避免会发生溢出的指令,下面来看看它的工作方式,我们就能知道个中源由。注:这里所说的除法溢出并不是指分母为0而发生溢出的情况。
div的工作方式:
(1)除数:有8位和16位两种,在一个寄存器或内存单元中
(2)被除数:默认放在AX或DX和AX中,如果除数为8位,则被除数为16位,默认在AX中存放;如果除数为16位,被除数为32位,在DX和AX中存放,DX存放高16位,AX存放低16位
(3)结果:如果除数为8位,则AL(AX的低8位)存储除法操作的商,AH(AX的高8位)存储除法操作的余数;如果除数为16们,则AX存储除法操作的商,DX存放除法操作的余数。
用一个表格来表示上述的工作方式,如下表所示:
除数
被除数
结果
8位
16位,AX
商:AL,余数:AH
16位
32位,DX(高16位)+AX(低16位)
商:AX,余数:DX
就这么一看似乎还没有什么问题,下面我就以一个例子来说明一下种工作方式下的除法的致命缺陷。
为了更加容易地说明,我们以除数为8位的情况来说明,假设我们的被除数为65535(16位的最大值)存储在AX中,除数为1,存储在CL中,然后执行除法指令: div CL。根据上面的说法,结果都是放在AX中的,余数为0,当然这没有问题,然而商为65535要放在AL中却是放不下的,因为AL能存放的最大值只为255,所以此时就会发生溢出。我们可以看到65535/1 = 255,这显然与我位正常的除法结果不符。
在这里你可以认为我举了一个非常极端的例子,但是这种情况却并不是极端的情况,对于除数为8位的除法,只要商在255以上就会发生这种溢出。除数为16位的原理及情况与这里相同,只是它是当商为65535以上是就会发生溢出而已。
二、如何解决这个溢出问题
既然我们知道了问题的根源,要解决它就不困难了。为了统一而且不发生溢出,我们可以把所有的除法的商都用32位来保存,即所有的被除数都用32位,所有的除数都用16位,所有的商都用32位,所有的余数都用16位来保存,就可以解决这个问题,因为一个数除以一个整数后,不可能大于其之前的值。而对于8位的除法,除数和被除数的高位全用0补全即可。为了达到这个目的,我们就不能使用默认的除法指令div了,而需要我们写代码来实现我们自定义的除法。
考虑到除法是一个常用的操作,所以我们可以编写一个子程序来实现除法,在进行除法运算时,直接调用我们自己定义的子程序来完成任务,而不直接使用div指令。
三、如何实现这个功能
要实现除法还得使用div指令,只是我们可以做一些特殊的处理,让我们自定义的除法不发生溢出,因为我们使用的是除数为16位的除法,也就是说,我们只要能保证除法的商不大于65535就不会发生问题。为了实现这个功能,我们首先要知道一个关于除法的公式(H表示X的高位,L表示X的低位):
X/N = int(H/N)* 2^16 + [rem(H/N)* 2^16+L]/N
这个公式告诉我们32位的被除数与16位的除数,可以拆分为两个除数和被除数都为16位的数的除法,然后通过加法来得到同样的结果,这个是非常重要的。因为我们可以把H和L独立起来考虑,当进行H/N时,因为H存储在DX中,我们可以先把DX中的内容复制到AX中(操作之前把AX的内容保存好),再把DX的内容置为0,这样产生的除法操作的商就一定能放在一个16位的寄存器AX中。对于公式中的其他除法运算也采用相同的操作,然后通过把除法之前产生的结果进行相加,就能产生我们的无溢出除法子程序。
四、实现代码
基于这个公式,我们实现的代码如下:
;子程序名称:divdw  
;功能:进行不会产生溢出的除法运算,被除数为dword型  
;      除数为word型,结果为dword型  
;参数:    (ax)=dword型数据的低16位  
;       (dx)=dword型数据的高16位  
;       (cx)=除数  
;返回:    (dx)=结果的高16位,(ax)=结果的低16位  
;       (cx)=余数  
;计算公式:X/N=int(H/N)*2^16+[rem(H/N)*2^16+L]/N  
divdw:  
    jcxz divdw_return   ;除数cx为0,直

入党积极分子培训 来自淘豆网www.taodocs.com转载请标明出处.

相关文档 更多>>
非法内容举报中心
文档信息
  • 页数29
  • 收藏数0 收藏
  • 顶次数0
  • 上传人wz_198613
  • 文件大小3.81 MB
  • 时间2018-08-23