You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

TASM汇编大写转小写代码故障:键盘输入无法正常执行

修复TASM大写转小写程序的键盘输入问题

我来帮你梳理代码里的核心问题,一步步修复让它能正常处理键盘输入,完成大写转小写、输出结果并统计字符数的功能:

原代码的主要问题

  • 循环控制完全失控:你用了LOOPNE L1,但LOOP系列指令依赖CX寄存器做循环计数器,可代码里根本没初始化CX的值,这会导致循环行为完全不可预测。另外,你只判断$作为结束符,但没处理用户按回车的情况,输入回车后程序会一直卡着。
  • 字符计数逻辑错误:当前只有输入空格时才会INC BL,这和你要统计“读取的总字符数”的需求完全不符,应该每读取一个有效字符(非结束符)就计数一次。
  • 字符串结束符缺失INT 21H的09H功能需要字符串以$结尾才能正常输出,原代码没在缓冲区末尾添加这个结束符,会导致输出乱码。
  • 计数输出有bugADD BL, 01会多统计一个字符,而且如果字符数超过9,原代码只能输出单个数字,没法显示两位的数值。

修正后的完整代码

DATA SEGMENT PARA PUBLIC 'DATA'
    SIR DB 101 DUP (?) ; 多留1个位置存字符串结束符$
    newline DB 10,13,'$'
    count_prompt DB 10,13,'Total characters read: $'
DATA ENDS

CODE SEGMENT PARA PUBLIC 'CODE'
    ASSUME CS:CODE, DS:DATA, ES:DATA

; 大写转小写的子过程
to_lower PROC FAR
    ; 如果不是大写字母,直接返回
    CMP AL, 'A'
    JB exit_proc
    CMP AL, 'Z'
    JA exit_proc
    ; 大写转小写,ASCII码差值为20H
    ADD AL, 20H
exit_proc:
    RET
to_lower ENDP

START PROC FAR
    PUSH DS
    XOR AX, AX
    PUSH AX
    MOV AX, DATA
    MOV DS, AX
    MOV ES, AX

    MOV CX, 100 ; 初始化最大字符数(最多读100个)
    MOV BL, 0   ; 初始化字符计数器
    MOV DI, OFFSET SIR
    CLD         ; 方向标志置0,STOSB会自动递增DI

read_loop:
    MOV AH, 01H ; 读取键盘输入并回显
    INT 21H

    ; 判断是否触发结束输入:回车(0DH)或$
    CMP AL, 0DH
    JE end_read
    CMP AL, '$'
    JE end_read

    ; 检查是否已经读满100个字符
    JCXZ end_read

    ; 调用大写转小写子过程
    CALL to_lower

    ; 将转换后的字符存入缓冲区
    STOSB
    INC BL      ; 字符计数+1
    LOOP read_loop ; CX减1,不为0则继续循环

end_read:
    ; 在缓冲区末尾添加$,确保09H功能能正确输出
    MOV BYTE PTR [DI], '$'

    ; 输出换行
    LEA DX, newline
    MOV AH, 09H
    INT 21H

    ; 输出转换后的文本
    MOV DX, OFFSET SIR
    MOV AH, 09H
    INT 21H

    ; 输出字符数提示
    LEA DX, count_prompt
    MOV AH, 09H
    INT 21H

    ; 处理两位数字的输出(最多100个字符,范围0-99)
    MOV AL, BL
    MOV AH, 0
    MOV DL, 10
    DIV DL      ; AL=十位数字,AH=个位数字
    MOV CL, AH  ; 暂存个位

    ; 输出十位
    MOV DL, AL
    ADD DL, 30H ; 转ASCII码
    MOV AH, 02H
    INT 21H

    ; 输出个位
    MOV DL, CL
    ADD DL, 30H
    MOV AH, 02H
    INT 21H

    ; 退出程序
    MOV AH, 4CH
    INT 21H
START ENDP
CODE ENDS
END START

关键修改说明

  1. 循环控制修复:初始化CX为100,用LOOP read_loop控制最多读取100个字符,同时支持回车和$两种结束输入的方式,符合日常键盘输入习惯。
  2. 计数逻辑修正:每读取一个有效字符(非结束符)就执行INC BL,准确统计读取的总字符数。
  3. 字符串结束符处理:输入结束后手动给缓冲区添加$,确保INT 21H 09H能正确输出转换后的文本,不会出现乱码。
  4. 字符数输出优化:支持两位数字的显示,解决原代码只能显示个位数的问题,适配最多100个字符的统计需求。

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

火山引擎 最新活动