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

DOS Debug汇编程序仅输出12个字符的问题排查求助

DOS Debug汇编程序输出截断问题排查

问题描述

我正在用DOS Debug开发汇编程序,需求如下:

  • 接收输入字符串
  • 统计每个字符的第0、2、3、6位二进制位之和,若和为偶数则将该字符替换为4(ASCII码0x34)
  • 最后倒序输出字符串

目前程序大部分功能正常,但存在输出截断问题:输入字符串abcdefghijklmn(共14个字符)时,实际输出为n4lk4i4g4e44(仅12个字符),预期输出应为n4lk4i4g4e44b4。怀疑是loop循环执行12次后停止,请求排查原因。

汇编代码

a800
db 50 00

a100
mov ah, 09
mov dx, 700
int 21
mov ah, 3f
mov dx, 800
int 21

a150
mov bx, 800
mov si, 0
jmp 250

a250
mov al, [bx+si]
mov cl, [bx+si]
mov byte [750], cl
cmp al, 20
jl 490
mov ah, 0
clc
rcr al, 1
adc ah, 0
clc
rcr al, 2
adc ah, 0
clc
rcr al, 1
adc ah, 0
clc
rcr al, 4
adc ah, 0
mov al, ah
mov ah, 0
clc
rcr al, 1
adc ah, 0
cmp ah, 0
jg 300
jmp 320

a300
mov byte [bx+si], 34
inc si
jmp 250

a320
mov byte [bx+si], [750]
inc si
jmp 250

a490
mov byte [bx+si+1], 24
xor dx, dx
jmp 500

a500
mov ah, 02
mov dl, [bx+si]
int 21
dec si
loop 500
mov ah, 4c
int 21

a700
db "Iveskite teksta " 0A 0D "$"

n bb.com
r cx
1000
w
q

代码段说明:

  • a250:统计字符指定二进制位的和
  • a490:在字符串末尾添加$符号

问题原因分析

1. loop循环计数器未正确初始化

loop指令依赖CX寄存器作为循环计数器,每次执行会自动将CX减1,直到CX=0时停止。但你的程序存在两个关键问题:

  • 调用int 21h的0x3F号输入读取功能后,CX寄存器的值会被系统调用修改(0x3F功能执行过程中会改变CX的原始值)
  • 进入倒序输出的a500代码段前,从未将CX赋值为输入字符串的有效长度,导致CX为随机垃圾值(此处恰好为12),循环仅执行12次就终止,造成输出截断。

2. 输入长度处理异常

原代码调用0x3F读取输入时,未设置BX(标准输入句柄,需设为0)和CX(最大读取字节数,对应a800处定义的50),且未保存系统调用返回的实际读取字节数(存在AX中),导致无法准确获取输入字符串的有效长度。

3. 位统计逻辑错误

原代码用rcr移位指令统计位之和,多次移位会破坏原始字符值,且判断终止的条件cmp al,20会误将回车符以外的控制字符判定为结束,导致部分字符未被处理。


修复方案

1. 正确读取输入并保存长度

修改a100代码段,补全输入读取的参数,并保存实际读取长度:

a100
mov ah, 09
mov dx, 700
int 21
mov ah, 3f
mov bx, 0 ; 指定标准输入句柄
mov cx, 50 ; 对应缓冲区最大长度
mov dx, 800
int 21
mov [802], ax ; 保存实际读取的字节数到内存

2. 初始化循环计数器

修改a490代码段,设置CX为有效字符长度,并修正$符号的位置:

a490
mov byte [bx+si], 24 ; 覆盖回车符位置,无需+1
mov cx, [802]
dec cx ; 去掉回车符,得到有效字符数
mov si, cx ; 让SI指向最后一个有效字符的索引
jmp 500

3. 修正位统计逻辑

用test指令安全提取指定二进制位,避免破坏原始字符:

a250
mov al, [bx+si]
mov cl, al ; 保存原始字符
cmp al, 0D ; 仅在遇到回车符时结束处理
je 490
mov ah, 0
test al, 00000001b ; 检查第0位
jnz inc_ah
jmp skip0
inc_ah: inc ah
skip0:
test al, 00000100b ; 检查第2位
jnz inc_ah2
jmp skip2
inc_ah2: inc ah
skip2:
test al, 00001000b ; 检查第3位
jnz inc_ah3
jmp skip3
inc_ah3: inc ah
skip3:
test al, 01000000b ; 检查第6位
jnz inc_ah6
jmp skip6
inc_ah6: inc ah
skip6:
test ah, 1 ; 判断和是否为偶数
jnz 320 ; 和为奇数,保留原字符
jmp 300 ; 和为偶数,替换为4

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.15 05:40:22