汇编语言两数相加程序运行异常,请求代码问题排查
汇编求和程序问题排查与修复
你的代码存在几个关键问题,导致无法正常运行,以下是具体问题和修复方案:
1. convert_to_number 循环终止条件错误
原代码用 cmp bl, 0 判断循环结束,但INT 0AH读取的输入缓冲区中,用户输入的字符末尾没有0,实际输入长度存在buffer[1]中。原循环会持续读取内存直到遇到0,导致错误转换甚至程序崩溃。
修复:
利用已加载到cx的实际输入字符数控制循环次数,修改convert_to_number:
convert_to_number: xor ax, ax convert_loop: mov bl, byte ptr [si] sub bl, '0' mov dx, ax mov ax, 10 mul dx add ax, bx inc si loop convert_loop ; 用cx控制循环,直到计数为0 convert_done: ret
2. 输入后未处理换行,输出混乱
用户输入数字按回车后,回车符残留会导致后续提示信息显示位置错乱,需在每次读取完数字后输出换行。
修复:
在存储num1和num2后添加换行输出:
; 存储第一个数字后添加 mov ah, 9 lea dx, newline int 21h ; 存储第二个数字后添加 mov ah, 9 lea dx, newline int 21h
3. convert_to_ascii 缓冲区偏移与空间不足
原buffer仅预留6个字节存储转换后的ASCII,最多容纳3位数字,求和结果超过3位会溢出;且显示时直接指定buffer + 5的偏移错误,无法指向转换后的字符串起始位置。
修复:
- 扩大缓冲区预留空间:
buffer db 10, ?, 10 dup('$') ; 支持最多9位输入,预留10位存储转换结果 - 修改
convert_to_ascii,返回转换后的字符串起始地址到dx:convert_to_ascii: mov bx, 10 mov si, offset buffer + 10 ; 从缓冲区末尾往前写 mov byte ptr [si], '$' convert_loop2: xor dx, dx div bx add dl, '0' dec si mov [si], dl test ax, ax jnz convert_loop2 mov dx, si ; 将起始地址存入dx,供显示调用 ret - 调整显示代码,直接使用返回的
dx:; Convert sum to ASCII mov ax, sum call convert_to_ascii ; Display sum mov ah, 9 int 21h ; dx已指向转换后的字符串起始位置
4. 可选优化:重置输入缓冲区
两次复用同一个buffer,建议每次读取前重置计数位,避免残留数据干扰:
; 读取第一个数字前添加 mov buffer[1], 0 ; 读取第二个数字前添加 mov buffer[1], 0
修复后的完整代码
.model small .stack 100h .data message1 db 'Enter the first number: $' message2 db 'Enter the second number: $' result_message db 'The sum is: $' newline db 13, 10, '$' buffer db 10, ?, 10 dup('$') num1 dw ? num2 dw ? sum dw ? .code main: mov ax, @data mov ds, ax ; 提示输入第一个数字 mov ah, 9 lea dx, message1 int 21h ; 读取第一个数字 mov buffer[1], 0 mov ah, 0ah lea dx, buffer int 21h mov si, offset buffer + 2 mov cx, 0 mov cl, buffer[1] call convert_to_number mov num1, ax ; 换行 mov ah, 9 lea dx, newline int 21h ; 提示输入第二个数字 mov ah, 9 lea dx, message2 int 21h ; 读取第二个数字 mov buffer[1], 0 mov ah, 0ah lea dx, buffer int 21h mov si, offset buffer + 2 mov cx, 0 mov cl, buffer[1] call convert_to_number mov num2, ax ; 换行 mov ah, 9 lea dx, newline int 21h ; 求和 mov ax, num1 add ax, num2 mov sum, ax ; 显示结果提示 mov ah, 9 lea dx, result_message int 21h ; 转换结果为ASCII mov ax, sum call convert_to_ascii ; 显示求和结果 mov ah, 9 int 21h ; 换行 mov ah, 9 lea dx, newline int 21h ; 退出程序 mov ax, 4c00h int 21h convert_to_number: xor ax, ax convert_loop: mov bl, byte ptr [si] sub bl, '0' mov dx, ax mov ax, 10 mul dx add ax, bx inc si loop convert_loop convert_done: ret convert_to_ascii: mov bx, 10 mov si, offset buffer + 10 mov byte ptr [si], '$' convert_loop2: xor dx, dx div bx add dl, '0' dec si mov [si], dl test ax, ax jnz convert_loop2 mov dx, si ret end main
内容的提问来源于stack exchange,提问作者Jihye Lee
相关产品推荐
相关产品推荐

