FASM技术求助:循环实现数组输入及字符串转大写输出代码故障排查
FASM实现字符串转大写并存储输出的解决方案
Hey there! 我猜你的FASM代码大概率在输入处理、大小写转换逻辑或者数组存储/输出的环节踩了坑。下面我会给你一个完整的可运行示例,同时拆解关键步骤帮你理清问题所在。
完整可运行代码(DOS平台)
format MZ entry start stack 100h section '.data' data readable writable input_buf db 255, 0, 255 dup(0) ; 输入缓冲区:最大长度255,实际输入长度占位,字符存储区 output_arr db 255 dup(0) ; 用于存储大写后的字符数组 newline db 0Dh, 0Ah, '$' ; 换行符,方便输出排版 section '.code' code readable executable start: ; 1. 获取用户输入的字符串 mov ah, 0Ah mov dx, input_buf int 21h ; 2. 将字符串转为大写并存入output_arr mov si, input_buf + 2 ; SI指向第一个实际输入的字符 mov di, output_arr ; DI指向输出数组的起始位置 mov cl, [input_buf + 1] ; CL存储实际输入的字符长度 mov ch, 0 ; 清空CH,让CX成为完整的循环计数器 convert_loop: mov al, [si] ; 读取当前字符到AL ; 判断是否为小写字母(ASCII范围97-122) cmp al, 'a' jl skip_convert ; 小于'a',跳过转换 cmp al, 'z' jg skip_convert ; 大于'z',跳过转换 sub al, 32 ; 小写转大写:ASCII值减32 skip_convert: mov [di], al ; 将处理后的字符存入数组 inc si ; 移动输入指针到下一个字符 inc di ; 移动输出数组指针到下一个位置 loop convert_loop ; 循环直到所有字符处理完成 ; 在输出数组末尾添加DOS打印功能的结束标记'$' mov byte [di], '$' ; 3. 输出转换后的大写字符串 mov ah, 09h mov dx, output_arr int 21h ; 输出换行,优化输出体验 mov ah, 09h mov dx, newline int 21h ; 正常退出程序 mov ah, 4Ch int 21h
关键步骤解析
- 输入缓冲区格式:DOS的
0Ah号中断要求缓冲区必须是「最大长度字节 + 实际长度占位字节 + 字符存储区」的格式,这是很多新手容易忽略的点,写错会导致输入读取异常。 - 大小写转换逻辑:只对小写字母(
a-z)执行减32的操作,避免修改数字、符号等非字母字符,保证转换的准确性。 - 数组存储:用
DI寄存器跟踪输出数组的当前位置,每处理一个字符就存入并移动指针,最后必须添加$——DOS的09h打印功能依赖这个标记来确定输出结束位置,没加会导致乱码。 - 循环控制:用
CX寄存器作为循环计数器,必须清空CH确保循环次数等于实际输入的字符数,否则会多循环或少循环。
常见错误排查
- 忘记给输出字符串添加
$结束符,导致打印出一堆乱码 - 输入缓冲区格式错误,比如没预留「实际长度」的占位字节
- 转换时未判断字符范围,导致数字、符号被错误修改
- 循环计数器设置错误(比如没清零
CH),导致字符处理不完整或越界
内容的提问来源于stack exchange,提问作者Karl Philipp Sy Fabre
相关产品推荐
相关产品推荐

