zhzwsaber 发表于 2022-9-20 11:35:00

dos界面貌似卡死在死循环,但是debug调试能正常退出

按照王爽汇编第四版实验10
显存上面写内容
除法运算
这两个函数分开单独运行都很正常。
结合到一起以后直接运行就直接卡死了,我debug去走一遍,里面可以正常运行到int 21h
我不明白到底哪儿出问题了
assume cs:code,ds:data
data segment
    dw 12666,444,1,8,3,38
    db 30 dup(0)
data ends
code segment
    begin:
    mov ax,data
    mov ds,ax
    mov si,0
    mov bx,10
    mov cx,6
    mov di,16

    s1:
    call dtoc         ;调用函数dtoc
    add si,2
    loop s1            

    mov si,16         ;为调用函数show_str前做必要参数的初始化
    mov dh,2
    mov dl,3
    mov cl,2
    call show_str       ;调用函数show_str

    mov ax,4c00h      ;退出程序
    int 21h


    dtoc:               ;进入函数dtoc,保存变量si,cx
    push si
    push cx
    mov ax,ds:      ;将需要运算的被除数放入ax
    mov si,0            ;si置0,作为压栈计数器
    instack:            ;数内循环,将数据进制转为10进制每位数存入一个字节单元
    div bx            ;除数(bx)=10
    add dx,30h          ;余数(dx)=(dx)+30h为10进制每位数的ascii码
    push dx             ;余数(dx)压栈
    inc si            ;用si计算压栈次数
    mov dx,0
    mov cx,ax
    jcxz ok      
    jmp instack
    ok:
    mov cx,si         ;cx计算将要出栈的次数
    outstack:
    pop ds:
    inc di
    loop outstack
    pop cx            ;还原变量cx,si
    pop si
    ret               ;函数dtoc返回


    show_str:         ;进入函数show_str
    push cx
    mov ax,0B800H
    mov es,ax         ;es为0B800h显存的段地址

    mov cx,2000         ;设定循环2000次,正好完整清屏
    mov al,0h
    mov di,0
    init:               ;初始化清屏开始
    mov es:,al
    add di,2
    loop init


    mov al,80         ;计算应该从显存的哪一个地址开始存数据
    sub dh,1
    mul dh
    sub dl,1
    mov dh,0
    add ax,dx
    add ax,ax
    mov di,ax

    pop cx            ;字体颜色存放进bl
    mov bl,cl
    s:
    mov ch,0
    mov cl,ds:      ;cl存放具体数据
    jcxz ok1            ;如果数据为00跳出
    mov es:,cl      ;数据cl,颜色bl放进显存对应地址
    mov es:,bl
    inc si
    add di,2
    jmp s

    ok1:
    ret               ;函数show_str返回

code ends
end begin

zhzwsaber 发表于 2022-9-20 15:58:22

自问自答,原来debug的时候会自动把dx置为0,而直接运行却不会,就这里出问题导致的死循环
页: [1]
查看完整版本: dos界面貌似卡死在死循环,但是debug调试能正常退出