lcmystery 发表于 2016-4-30 13:19

【笔记】X86 (16位) 汇编笔记【防除法溢出】

本帖最后由 lcmystery 于 2016-4-30 13:24 编辑

;
;解决除法溢出,公式:被除数高16位/除数*65536+(被除数高16位%除数*65536+被除数低16位)/除数
;
;                                                *****消除除法溢出********
;                                                div,mul——除法,乘法指令
assume cs:code,ds:data,ss:stack
      data segment
      dw 000fh,4240h,000ah,0000h,0001h ;默认dx存储被除数的高16位,ax存放低16位(除数为16位时)。

   dw10 dup (0)
      data ends
      
      stack segment
      dw 20 dup (0)
      stack ends
      
      code segment
      start:mov ax,data
                mov ds,ax
                mov ax,stack
                mov ss,ax
                mov sp,20h
               
                call _div
                              
                mov ax,4c00h
                int 21h
               
_div:
      mov ax,ds:
      div word ptr ds:
      mov ds:,ax
      mov ax,ds:
      div word ptr ds:
      mov ds:,ax
      
      ret

      code ends

end start
      

上面是正确的编程。debug调试正确。


唉,开始做这实验,直接就按照公式编程,结果、、、、、
后来仅都 调试不对,仔细分析后发现、、、、太 坑爹了、、、

下面也是正确的编程,但是debug调试会得到错误的结果。


;
;解决除法溢出,公式:被除数高16位/除数*65536+(被除数高16位%除数*65536+被除数低16位)/除数
;
;                                                *****消除除法溢出********
;                                                div,mul——除法,乘法指令
assume cs:code,ds:data,ss:stack
      data segment
      dw 000fh,4240h,000ah,0000h,0001h ;默认dx存储被除数的高16位,ax存放低16位(除数为16位时)。
      data ends
      
      stack segment
      dw 20 dup (0)
      stack ends
      
      code segment
      start:mov ax,data
                mov ds,ax
                mov ax,stack
                mov ss,ax
                mov sp,20h
               
                call _div

               mov ax,0100h
               int 21h
                mov ax,4c00h
                int 21h
               
      _div:
                mov ax,0
                mov al,ds:
                mov cx,ds:
               
                div cl
               
                push ax ;商和余数
                mov ah,0
                mov cx,ds:
                mul cl
                mov dx,0
                mov dx,ax
                push ax ;低16位
                push dx ;高16位>>sp:18h
                mov sp,1ch
                pop ax ;商和余数
                mov al,0
                mul cx
                mov cx,0
                mov dx,ax
                mov ax,0
                adc ax,ds:
                mov cx,ds:
                ;mov dx,0
                div cx

                mov sp,18h
                pop cx
                add dx,cx ;高位相加
                pop cx
                add ax,cx ;低位相加
                mov sp,1eh

      ret
      code ends

end start
      


为什么呢?

原来debug提供单步调试。即单步中断。中断前总会把cs:ip都压入栈中,去执行中断程序。而且压入的栈段会共享你设置的栈段。(这样你进行mov sp,**)如果 ** 位于当前 sp的后面就会覆盖掉 原来栈段内的内容。



lcmystery 发表于 2016-4-30 13:21

本帖最后由 lcmystery 于 2016-4-30 13:25 编辑

{:301_992:}不喜勿喷啊。如果表述不完整,请见谅啊。谢谢。

wangqiustc 发表于 2016-4-30 13:37

来学习了,楼主厉害

Anyson 发表于 2016-4-30 15:38

楼主好腻害

TaiLan 发表于 2016-5-2 22:55

感谢分享。。
页: [1]
查看完整版本: 【笔记】X86 (16位) 汇编笔记【防除法溢出】