代码改变世界

编写不会产生除法溢出的子程序

  youxin  阅读(317)  评论(0编辑  收藏  举报

divdw:           不溢出除法,被除数为dword,除数为word,结果为dword 

;参数:(dx):(ax)=被除数高、低16位  (cx)=除数 
;返回:(dx):(ax)=结果的高、低16位  (cx)=余数 

h,L表示被除数H的高16位和低16位,int(h/n)取商,rem(h/n)取余。n代表除数.

 采用公式:x/n=int(h/n)*65536+[rem(h/n)*65536+L]/n 

即:int(h/n)作高16位,             rem(h/n)做被除数高16位,L做低16位,除以n 的结果做 低16位。

最开始相当很复杂,答案很简单:

复制代码
assume cs:code

code segment
start:mov ax,4240h ;dword型数据的低16位
        mov dx,000fh ;dword型数据的高16位
        mov cx,0Ah   ; c除数
        call divdw 
        mov ax,4c00h
        int 21h

divdw:   push si
         push ax
         mov ax,dx ;ax存储高位
         mov dx,0
         div cx
         mov si,ax ;si存储商,dx存放余数
         
         pop ax ;ax存储低位
         div cx   ;运算后ax存储结果的低位
         
         mov cx,dx ;余数
         mov dx,si ;dx存储高位
         pop si
         
         ret


  code ends
  end start
复制代码

 

  下面是自己写的一段简洁的代码:

复制代码
divdw:
        mov di,ax 
        mov ax,dx ;ax 存储高16位
        mov dx,0
        div cx ;ax 商,dx余
         
        push ax
        
        mov ax,di
        div cx  ;ax运算后为余安照公式存储低16位
        mov  cx,dx ;存储余数,最开始忘记了
        
        pop dx ;dx接受开始的ax
        
        ret
复制代码

下面的代码跟以上类似:

复制代码
divdw: ;子程序定义开始

push ax

mov ax,dx

mov dx,0

div cx

mov bx,ax

pop ax

div cx

mov cx,dx

mov dx,bx

ret ;子程序定义结束
复制代码

 

编辑推荐:
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
阅读排行:
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本
· Manus爆火,是硬核还是营销?
· 终于写完轮子一部分:tcp代理 了,记录一下
· 别再用vector<bool>了!Google高级工程师:这可能是STL最大的设计失误
· 单元测试从入门到精通
点击右上角即可分享
微信分享提示