王爽《汇编语言》实验10中的dtoc子程序,运行不了,但是单步调试可以通过并且结果正常,我的代码如下:
assume cs:code
data segment
db 10 dup (0)
data ends
code segment
start:
mov ax,12666
mov bx,data
mov ds,bx
mov si,0
call dtoc
mov dh,8
mov dl,3
mov cl,2
call show_str
mov ax,4c00h
int 21h
dtoc:
; (ax)=w data, ds:si=first address of str
mov cx,5
mov bx,10
mov di,0
s0:
div bx
add dl,30h
mov [di],dl
inc di
mov dx,0
loop s0
ret
show_str:
; (dh)=line_num (0~24), (dl)=column_num (0~79)
; (cl)=color, ds:si=source address
mov ax,0b800h
mov es,ax
mov al,dh ; calculate the address
mov ah,0
mov dh,80
mul dh
mov dh,0
add ax,dx
add ax,ax
mov bx,ax
mov al,cl ; store the color
mov cx,0
s:
mov cl,[si]
jcxz show_str_ret
mov es:[bx],cl
inc bx
mov es:[bx],al
inc bx
inc si
loop s
show_str_ret:
ret
code ends
end start
单步调试正常:
但是直接运行就会卡住:
后来我又在virtualbox的dos虚拟机上试了试,出现了除法溢出。才知道原来dosbox中出现了除法溢出引起的中断是不会正常返回的。
可是为什么会溢出呢?我在编程的时候还专门考虑了这个问题,所以选用的是div bx,即16位的除法,这么也不可能溢出啊。再说了就算是溢出那为什么debug的时候又没事呢?
思前想后。纠结了我好久。
最后终于发现问题了,是在div bx之前没有把mov dx,0。dx中还有数,于是就会导致溢出。
那么为什么在debug中又没事呢?原来是因为debug加载的时候会对寄存器进行初始化,也就是debug帮我做了mov dx,0这一步。
只要在div bx之前加一句mov dx,0,问题就迎刃而解了。