EMU8086数组求和汇编程序问题求助:输入错位、结果异常
问题分析与修复方案
核心问题拆解
1. 输入提示换行错乱
DOS 0Ah输入函数执行后,用户输入的回车未被正确处理,导致光标位置异常;同时直接用数组元素作为输入缓冲区,违反了0Ah函数要求的缓冲区格式(首字节为最大输入长度,次字节为实际输入长度,后续为字符存储区),进一步加剧显示混乱。
2. 数值转换与求和异常
仅处理单个字符的ASCII转数字,未支持多位数输入;缓冲区格式错误导致读取的输入内容完全错误,最终求和结果不符合预期。
3. 求和结果输出乱码
使用字符串输出函数(09h)直接输出数值变量,09h仅能输出以$结尾的ASCII字符串,数值的二进制内容会被解析为乱码。
修正后的完整代码
TITLE ArraySumInput X (ArraySumInput.asm) ; 接收用户输入5个整数存入数组并计算总和的程序 ; Yemi ; 2023年12月8日 org 100h .DATA array_size DW 5 array DW 5 DUP(0) ; 初始化数组元素为0 sum DW 0 prompt_msg DB "请输入一个整数: $" ans_msg DB "总和是: $" newline_msg DB 13, 10, "$" ; 换行与回车控制符 input_buf DB 5, ?, 5 DUP(0) ; 专用输入缓冲区:最大长度、实际长度、字符存储区 .CODE main PROC ; 接收数组元素输入 mov cx, array_size ; 设置循环计数器为数组大小 lea si, array ; 加载数组基地址到SI寄存器 input_loop: ; 输出换行,重置光标位置 mov ah, 09h lea dx, newline_msg int 21h ; 显示输入提示信息 mov ah, 09h lea dx, prompt_msg int 21h ; 读取用户输入的字符串 mov ah, 0Ah lea dx, input_buf int 21h ; 将输入字符串转换为16位整数 mov ax, 0 ; 初始化转换结果为0 mov bl, [input_buf+1] ; 获取实际输入的字符长度 lea di, input_buf+2 ; 指向输入字符串的第一个字符 convert_loop: mov cl, [di] sub cl, '0' ; ASCII字符转十进制数字 mov ch, 0 push bx mov bx, 10 mul bx ; 当前结果乘以10,准备累加下一位 pop bx add ax, cx ; 累加当前位数字 inc di dec bl jnz convert_loop ; 循环处理所有输入字符 mov [si], ax ; 将转换后的整数存入数组 add si, 2 ; 移动到下一个16位数组元素 loop input_loop ; 循环直到输入完所有元素 ; 计算数组元素总和 mov cx, array_size ; 重置循环计数器 lea si, array ; 重置数组基地址 mov sum, 0 ; 初始化总和为0 sum_loop: mov ax, [si] ; 加载当前数组元素到AX add sum, ax ; 累加到总和变量 add si, 2 ; 移动到下一个元素 loop sum_loop ; 循环结束 ; 换行并显示结果提示 mov ah, 09h lea dx, newline_msg int 21h mov ah, 09h lea dx, ans_msg int 21h ; 调用子程序输出总和数值 mov ax, sum call print_number ; 正确退出程序 mov ah, 4Ch int 21h main ENDP ; 子程序:将AX中的16位有符号整数转换为ASCII字符串并输出 print_number PROC push bx push cx push dx mov cx, 0 ; 记录数字位数的计数器 mov bx, 10 ; 十进制除数 ; 处理负数 test ax, 8000h jz positive push ax mov dl, '-' mov ah, 02h int 21h pop ax neg ax ; 取负数的绝对值 positive: ; 逐位提取数字并压入栈中 digit_loop: xor dx, dx div bx push dx ; 余数(对应一位数字)入栈 inc cx cmp ax, 0 jnz digit_loop ; 从栈中弹出数字并输出 print_loop: pop dx add dl, '0' ; 数字转ASCII字符 mov ah, 02h int 21h loop print_loop pop dx pop cx pop bx ret print_number ENDP END main
关键修复细节说明
- 专用输入缓冲区: 新增
input_buf符合DOS 0Ah函数的格式要求,避免破坏数组结构。 - 完整数值转换: 实现了多位数和负数的字符串转整数逻辑,覆盖常规输入场景。
- 数值输出子程序:
print_number将二进制数值转换为ASCII字符串后逐字符输出,彻底解决乱码问题。 - 规范程序退出: 使用DOS 4Ch函数正确终止程序,避免多余指令导致的异常。
内容的提问来源于stack exchange,提问作者Obj
相关产品推荐
相关产品推荐

