今天在写汇编的时候遇到一个很奇葩的问题,用Debug调试的时候能够很完美的结束。但是在运行程序的时候却进入了死循环。我都不知道这是为什么,然后我进行调试,这 次调试的方法我不是用debug直接一步步的调试 assume cs:code,ds:data,ss:stack data segment db 10 dup (0) data ends stack segment dd 0,0,0,0 stack ends code segment start: mov ax, stack mov ss, ax mov sp, 17 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: mov bh, 0 mov bl, 10 div bx mov ch, 0 mov cl, dl jcxz ok mov dx, 0 add cl, 30h mov ds:[si], cl inc si jmp short dtoc ok: ret show_str: mov si, 0 mov ch, 0 mov al, 09fh mul dh mov bx, ax mov al, 2 mul dl mov dx, ax add bx, dx add bx, 6 mov ax, 0b800h mov es, ax mov dx, cx s: mov cl, ds:[si] mov ch, 0 jcxz ok1 mov es:[bx + si], cl inc bx mov es:[bx + si], dl inc si jmp short s ok1: ret code ends end start 运行结果是: 这是我的错误代码,因为我代码里面有2个子函数。一个是数值和ascii显示字符之间的转换,一个是在往显存里面写数据。 1、注释我的转换代码dtoc assume cs:code,ds:data,ss:stack data segment db '1','2','6','6','6',0 data ends stack segment dd 0,0,0,0 stack ends code segment start: mov ax, stack mov ss, ax mov sp, 17 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: ; mov bh, 0 ; mov bl, 10 ; div bx ; mov ch, 0 ; mov cl, dl ; jcxz ok ; mov dx, 0 ; add cl, 30h ; mov ds:[si], cl ; inc si ; jmp short dtoc ; ;ok: ret show_str: mov si, 0 mov ch, 0 mov al, 09fh mul dh mov bx, ax mov al, 2 mul dl mov dx, ax add bx, dx add bx, 6 mov ax, 0b800h mov es, ax mov dx, cx s: mov cl, ds:[si] mov ch, 0 jcxz ok1 mov es:[bx + si], cl inc bx mov es:[bx + si], dl inc si jmp short s ok1: ret code ends end start 结果是: 是正确的,那我是我的dtoc错误了? assume cs:code,ds:data,ss:stack data segment db 10 dup (0) data ends stack segment dd 0,0,0,0 stack ends code segment start: mov ax, stack mov ss, ax mov sp, 17 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: mov bh, 0 mov bl, 10 div bx mov ch, 0 mov cl, dl jcxz ok mov dx, 0 add cl, 30h mov ds:[si], cl inc si jmp short dtoc ok: ret ;show_str: ; mov si, 0 ; mov ch, 0 ; mov al, 09fh ; mul dh ; mov bx, ax ; mov al, 2 ; mul dl ; mov dx, ax ; add bx, dx ; add bx, 6 ; mov ax, 0b800h ; mov es, ax ; mov dx, cx ; ;s: mov cl, ds:[si] ; mov ch, 0 ; jcxz ok1 ; mov es:[bx + si], cl ; inc bx ; mov es:[bx + si], dl ; inc si ; jmp short s ; ;ok1: ret code ends end start 结果: 也是这样,我又检查代码。发现是可以这样做的啊,能够写进data数据段。我猜想难道是在做除法的时候dx没有赋值为0么? 修改代码: assume cs:code,ds:data,ss:stack data segment db 10 dup (0) data ends stack segment dd 0,0,0,0 stack ends code segment start: mov ax, stack mov ss, ax mov sp, 17 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: mov dx, 0 mov bh, 0 mov bl, 10 div bx mov ch, 0 mov cl, dl jcxz ok add cl, 30h mov ds:[si], cl inc si jmp short dtoc ok: ret ;show_str: ; mov si, 0 ; mov ch, 0 ; mov al, 09fh ; mul dh ; mov bx, ax ; mov al, 2 ; mul dl ; mov dx, ax ; add bx, dx ; add bx, 6 ; mov ax, 0b800h ; mov es, ax ; mov dx, cx ; ;s: mov cl, ds:[si] ; mov ch, 0 ; jcxz ok1 ; mov es:[bx + si], cl ; inc bx ; mov es:[bx + si], dl ; inc si ; jmp short s ; ;ok1: ret code ends end start 结果: 通过了,最后我将注释去掉: assume cs:code,ds:data,ss:stack data segment db 10 dup (0) data ends stack segment dd 0,0,0,0 stack ends code segment start: mov ax, stack mov ss, ax mov sp, 17 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: mov dx, 0 mov bh, 0 mov bl, 10 div bx mov ch, 0 mov cl, dl jcxz ok add cl, 30h mov ds:[si], cl inc si jmp short dtoc ok: ret show_str: mov si, 0 mov ch, 0 mov al, 09fh mul dh mov bx, ax mov al, 2 mul dl mov dx, ax add bx, dx add bx, 6 mov ax, 0b800h mov es, ax mov dx, cx s: mov cl, ds:[si] mov ch, 0 jcxz ok1 mov es:[bx + si], cl inc bx mov es:[bx + si], dl inc si jmp short s ok1: ret code ends end start 结果: 正确了,这是为什么呢?就算是bx中有值也不会出现死循环啊!哪位大神看到了能否解答一下。