You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在DOSBox中用TASM编写的汇编代码异常:无限循环且未达预期

解决TASM汇编逐步打印名字的无限循环问题

原代码的核心问题

  • 寄存器误用:mov di,[bx]将字符串的字符值(而非地址)存入di,完全偏离了buffer的用途,且INT 21H的09H功能要求DX指向字符串首地址,原代码直接传字符值必然出错。
  • 循环逻辑断裂:dec count2后直接jnz outer_loop,导致后续的print_prev和next代码永远无法执行,直接陷入无限循环。
  • 字符串打印错误:09H功能需要字符串以$结尾,原代码未处理结束符,无法正确打印。
  • Delay逻辑位置错误:在未完成当前打印步骤就进入delay循环,阻塞了流程。

修正后的代码

.MODEL SMALL
.STACK 64
.DATA
my_string db "Carlton"  ; 7个字符,无需0结尾
count1 db 07            ; 名字长度
buffer db 8 dup(0)      ; 预留空间存字符+结束符$
count2 dw 0FFFFh        ; 延时计数器
.CODE
MAIN:
    mov ax,@DATA
    mov ds,ax

    mov bx, offset my_string  ; 指向原字符串首地址
    mov di, offset buffer     ; 指向buffer首地址
    mov byte ptr [di+7], '$'  ; 预先设置buffer的结束符,避免每次循环设置

outer_loop:
    ; 清屏
    MOV AX,0600H
    MOV BH,07
    MOV CX,0000
    MOV DX,184FH
    INT 10H
    
    ; 设置光标到屏幕中央(名字长度7,列位置39-3=36,确保居中)
    MOV AH,02
    MOV BH,00
    MOV DL,36
    MOV DH,12
    INT 10H

    ; 将当前字符复制到buffer
    mov al, [bx]
    mov [di], al

    ; 打印当前buffer中的字符串(逐步增加的名字片段)
    mov ah,09h
    mov dx, offset buffer
    int 21h

    ; 延时循环
    mov cx, count2
delay_loop:
    dec cx
    jnz delay_loop

    ; 移动指针,准备下一个字符
    inc bx
    inc di
    dec count1
    jnz outer_loop  ; 未打印完所有字符则继续循环

    ; 退出程序
    mov ah,4ch
    int 21h
END MAIN

关键修正说明

  1. Buffer处理:预先在buffer末尾存入$,每次循环只需要将当前字符写入buffer的对应位置,确保09H功能能正确识别字符串结尾。
  2. 循环逻辑修复:将delay放到打印完成后,确保每次打印完当前片段再延时,且外层循环判断count1是否为0,控制循环次数(7次,对应名字的7个字符)。
  3. 光标位置调整:原列位置39是屏幕中心,但名字长度为7,调整为36后,完整的"Carlton"能刚好居中显示。
  4. 字符串打印修正:使用dx, offset buffer指向buffer首地址,符合INT 21H 09H功能的要求。
  5. 寄存器使用修正:用al中转字符,正确复制到buffer,而非错误地修改di的地址值。

内容的提问来源于stack exchange,提问作者Philosophia

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.05 01:15:30