zoukankan      html  css  js  c++  java
  • 《汇编程序》王爽实验10.2的解法

    汇编语言中div运算如果被除数为32位,除数则为16位,被除数放在DX和AX中,商放在AX中,余数放在DX中。如果被除数为16位,除数则为8位,被除数放在AX中,商放在ah,余数放在al。

    但会产生一个问题,那就是当除出来的商大于AX或者AH的时候,就会产生除法溢出的错误。例如1000/1,被除数可以放在16位的AX中,1可以放在8位的寄存器中,得到的商为1000,超过了AH能容纳的最大值,因此会造成除法溢出的问题。

    王爽的书中提供一个公式,可以避免除法溢出的问题

    子程序要求


    名称:divdw
    功能:进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型
    参数:(ax)=dword型数据的低16位
      (dx)=dword型数据的高16位
      (cx)=除数
    返回:(ax)=商的低16位
      (dx)=商的高16位
      (cx)=余数

    公式


    X:被除数,范围:[0, FFFFFFFF]

    N:除数,范围:[0, FFFF]

    H:X高16位,范围:[0, FFFF]

    L:X低16位,范围:[0, FFFF]

    int():描述性运算符,取商,比如,int(38/10)=3

    rem():描述性运算符,取余数,比如,rem(38/10)=8

    公式:X/N = int(H/N)*65536+[rem(H/N)*65536+L]/N

    分析


    首先来看看公式中的65536,很多新手的话可能不能理解这个65536是什么意思,其实65536就是10000H,相当于2^16,也就是说是乘以2^16,意思就是左移16位。

    式中int(H/N)和rem(H/N)代表着X的高16位的商和余数。

    等式右边的int(H/N)*65536表示将H/N的商作为最终结果商的高位字。

    rem(H/N)*65536+L表示将H/N的余数左移16位,形成一个新的dword数据的高16位,L作为低16位。

    最后的结果是DX中存放int(H/N)的结果,AX中存放(rem(H/N)*65536+L)/N的商,CX中存放(rem(H/N)*65536+L)/N的余数。

    子程序


      ;子程序描述
      ;名称: divdw
      ;功能: 进行不会产生溢出的除法运算,被除数为dword型,除数为word型,结果为dword型.
      ;参数: (dx)=dword型数据的高16位 (ax)=dword型数据的低16位 (cx)=除数
      ;返回: (dx)=结果的高16位 (ax)=结果的低16位        (cx)=余数
      ;应用举例: 计算1000000/10(F4240H/0AH) 
      divdw:
        push ax ;被除数的低16位入栈
        mov ax,dx
        mov dx,0
        mov cx,10
        div cx  ;得到的结果商放在AX中,余数放在DX中
        mov cx,ax;暂时保存商
        pop ax  ;取出低16位的值
        push cx ;保存商入栈
       
        mov cx,10
        div cx
       
        mov cx,dx   ;余数放入cx中
        pop dx  ;商的高16位存入dx中,ax中的结果就为商的低16位

      ret

  • 相关阅读:
    ZOJ 3018
    poj2464
    Gauss
    【C】关于内存地址
    【C】typedef与define的区别
    C位移操作
    操作系统使用批处理文件更改网络配置
    【Linux】查看某个进程的线程数量(转)
    数据结构快速排序
    C++Explanation of ++val++ and ++*p++ in C
  • 原文地址:https://www.cnblogs.com/cxjchen/p/2968824.html
Copyright © 2011-2022 走看看