【笔记】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:25 编辑
{:301_992:}不喜勿喷啊。如果表述不完整,请见谅啊。谢谢。 来学习了,楼主厉害 楼主好腻害 感谢分享。。
页:
[1]