在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
关键修正说明
- Buffer处理:预先在buffer末尾存入
$,每次循环只需要将当前字符写入buffer的对应位置,确保09H功能能正确识别字符串结尾。 - 循环逻辑修复:将delay放到打印完成后,确保每次打印完当前片段再延时,且外层循环判断
count1是否为0,控制循环次数(7次,对应名字的7个字符)。 - 光标位置调整:原列位置39是屏幕中心,但名字长度为7,调整为36后,完整的"Carlton"能刚好居中显示。
- 字符串打印修正:使用
dx, offset buffer指向buffer首地址,符合INT 21H 09H功能的要求。 - 寄存器使用修正:用
al中转字符,正确复制到buffer,而非错误地修改di的地址值。
内容的提问来源于stack exchange,提问作者Philosophia
相关产品推荐
相关产品推荐

