注册 登录  
 加关注
   显示下一条  |  关闭
温馨提示!由于新浪微博认证机制调整,您的新浪微博帐号绑定已过期,请重新绑定!立即重新绑定新浪微博》  |  关闭

信息 灵感 创新

I? =Information,Inspiration,Innovation

 
 
 

日志

 
 
关于我

we are 5. Mathematics, Computation, Programming, Engineering, and Making fun of life.

网易考拉推荐

div指令的使用及溢出处理  

2014-12-02 12:01:27|  分类: x86ASM |  标签: |举报 |字号 订阅

  下载LOFTER 我的照片书  |

我们知道,div指令的作用是进行除法运行,详细的操作如下:

格式:
div reg
div 内存单元

1、除数:有8位和16位两种,在一个寄存器或者内存中。
2、被除数:默认放在AX或(DX和AX)中,如果除数为8位,被除数为16位,被除数默认在AX中存放,如果除数为16位,被除数为32位,被? 除数则在(DX和AX)中存放,DX存放高16位,AX存放低16位。
3、结果:如果除数是8位,则AL存储除法操作的商,AH存储除法操作的余数;如果除数是16位,则AX存储除法操作的商,DX存储除法操作的余数。

列表如下:

方式 被除数 除数 余数
1 AX reg/addr8 AL AH
2 DX:AX reg16/addr16 AX DX

例如,计算3999/17,为了说明div的原理,这里先给出结果,商为235,余数为4。

分析计算过程因为3999=0F9FH,17=0011H,被除数能够用16位表示,而除数能用8位表示,使用方式1进行除法运算。我们必须将被除数放入AX中,而除数需要放入一个8位寄存器或者内存地址中,这里我们使用BL。代码如下:

assume cs:code
code segment
start:
    mov ax,0f9fh
    mov bl,11h
    div bl
    mov dx,ax
    mov ax,4c00h
    int 21h
code ends
end start

调试结果如下:

image

虽然结果是保存在AX中,但是为了让程序正常退出,使用了mov ax,4c00h,在这之前,我们先将AX中的结果保存到了DX中,查看DX中的结果是04EBH,根据前面的说明,EBH就是商,而04H则为余数,EBH=235,这与我们所期望的结果是一致的。

现在要计算87654321/8086,则先将87654321对应的十六进制值05397FB1H中的高16位0539H放入DX中,而低16位7FB1H则放入AX中,除数8086对应的十六进制值1F96H可以放入BX中,运行结果为:
div指令的使用及溢出处理 - Lemniscate - 信息,灵感,创新
 注意CX中应该是除法运算之后AX中的值。根据div的说明,CX(由AX传入CX中)的应该是商,而DX中则应该是余数。2A58H=10840,0821H=2081,检验可以发现87654321=10840*8086+2081确实如此。
这一切看上去是运行良好,没有任何问题。不过,等等,试试12345/10?按16位数除以8位数,结果大于8位数,导致除法错误,如果换成32位除以16位,就没有问题了。
再试试87654321/11?嗯,被除数比65535大,因此应该使用32位的被除数,显然,除数应该使用16位,我们可以使用一个通用寄存器,这都没问题,但是,87654321/11=7968574,余7,注意商比65535,不能用一个16位的寄存器保存,怎么办?
这个时候,我们可以将DX:AX继续作为被除数,除数放入一个寄存器中,例如CX,然后将高位,低位分别做除法,一共做两次除法,第一次的除法得到的余数乘以65536再加上低16位,即可计算,下面是一个小例程。
assume cs:code,ds:data,ss:stack
data segment
  dw 0539h,7fb1h,000bh
data ends

stack segment
  db 16 dup(0)
stack ends

code segment
start:
  mov ax,data
  mov ds,ax
  mov ax,stack
  mov ss,ax
  mov sp,10h
  mov bx,1234h
  mov dx,ds:[0];高位
  mov ax,ds:[2];低位
  mov cx,ds:[4];除数
  call divdw
  mov ax,4c00h
  int 21h
;函数例程:divdw
;说明:处理一个dword除以word可能产生溢出的除泿
;输入
; DX:被除数髿6使
; AX:被除数使6使
; CX:除数
;输出
; DX:商的高16
; AX:商的低16
; CX:余数
; 其他受影响寄存器:无
divdw:  
  pushf
  push bx
  push ax
  mov ax,dx
  mov dx,0000h
  div cx
  ;ax商(高位),dx余数
  mov bx,ax
  pop ax
  div cx
  ;ax中是商(低位),dx余数 
  mov cx,dx
  mov dx,bx
  pop bx
  popf
  ret 
code ends
end start
运行效果如下:
div指令的使用及溢出处理 - Lemniscate - 信息,灵感,创新
 注意CX中存放的是余数,显然为7,而商则为(DX)*16+(AX)=0079973EH=7968574,与前面所述结果相符。
  评论这张
 
阅读(529)| 评论(0)
推荐 转载

历史上的今天

评论

<#--最新日志,群博日志--> <#--推荐日志--> <#--引用记录--> <#--博主推荐--> <#--随机阅读--> <#--首页推荐--> <#--历史上的今天--> <#--被推荐日志--> <#--上一篇,下一篇--> <#-- 热度 --> <#-- 网易新闻广告 --> <#--右边模块结构--> <#--评论模块结构--> <#--引用模块结构--> <#--博主发起的投票-->
 
 
 
 
 
 
 
 
 
 
 
 
 
 

页脚

网易公司版权所有 ©1997-2016