汇编语言计算器无法获取输入问题求助
LC-3汇编计算器无法获取输入的问题修复
核心问题分析
你的程序卡在第一个输入环节无法继续,主要是以下几个关键错误导致:
- 输入判断逻辑失效:
ClearReg会清零所有寄存器,包括R6,但GetInput函数开头未重新加载NEG_FORTYEIGHT到R6,导致无法将输入的ASCII字符转换为数字,也无法识别回车等终止输入的字符,输入循环永远无法退出。 - 数据存储与读取不匹配:
GetInput把输入的数字存在num_temp2,但主程序用LD R1, num_temp读取,导致R1始终为初始值0。 - 操作符解码逻辑错误:当前对
codesArray中负数值的取反比较逻辑无法匹配输入的操作符,会进入无限循环或直接返回,后续流程无法执行。 - 语法错误:乘法函数中
AND R4, R2 #0缺少逗号,会导致汇编失败。 - 结果输出错误:直接用
OUT输出数值结果,OUT仅能输出ASCII字符,会导致乱码。
分步修复方案
1. 修复GetInput函数的数字转换逻辑
在函数开头加载NEG_FORTYEIGHT到R6,同时完善非数字输入的判断:
GetInput LD R6, NEG_FORTYEIGHT ; 加载-48,用于ASCII转数字 AND R3, R3, #0 ; 清零R3用于计数 AND R4, R4, #0 ; 清零R4用于存储累加数字 InputLoop GETC ; 读取字符到R0 OUT ; 回显输入 ADD R5, R0, R6 ; ASCII转数字(48-57 → 0-9) BRn InputDone ; 非数字(如回车)退出循环 ADD R5, R5, #-9 ; 判断是否大于9 BRp InputDone ; 大于9则退出 ; 执行 R4 = R4 * 10 + R5 AND R6, R6, #0 LD R7, ten ADD R2, R4, #0 MultiplyByTen ADD R6, R6, R2 ADD R7, R7, #-1 BRp MultiplyByTen ADD R4, R6, R5 ADD R4, R4, #9 ; 还原之前减的9 ADD R3, R3, #1 LD R6, NEG_FORTYEIGHT ; 重新加载-48 BR InputLoop InputDone ST R4, num_temp2 RET
2. 修正主程序的数据读取
将读取第一个数字的代码改为读取num_temp2:
JSR GetInput LD R1, num_temp2 ; 改为读取正确的存储位置
3. 修复操作符解码逻辑
直接用输入字符与codesArray中的负数值相加,结果为0则匹配,同时增加遍历终止条件防止无限循环:
DecodeOperation LD R3, codesArray ADD R4, R0, #0 DecodeLoop LDR R5, R3, #0 ADD R6, R4, R5 ; 输入字符 + 负的字符ASCII = 0则匹配 BRz ExecuteOperation ADD R3, R3, #1 ADD R3, R3, #-4 ; 检查是否遍历完4个操作符 BRp DecodeExit ADD R3, R3, #4 BRnzp DecodeLoop DecodeExit RET
4. 修正语法错误与结果存储
修复乘法函数的语法错误,并确保所有运算结果存入R4:
MULTIPLY AND R3, R3, #0 AND R4, R2, #0 ; 添加缺失的逗号 MULTIPLY_LOOP BRz DONE_MULTIPLY ADD R3, R3, R1 ADD R4, R4, #-1 BRnp MULTIPLY_LOOP DONE_MULTIPLY ADD R4, R3, #0 ; 将结果存入R4 BRnzp OPERATION_FINISHED
5. 添加数字转ASCII输出函数
新增PrintNumber函数将数值转换为ASCII字符串输出,替换原有的直接OUT:
; 将R0中的数值转换为ASCII字符串输出 PrintNumber ST R1, SaveR1 ST R2, SaveR2 ST R3, SaveR3 ST R4, SaveR4 AND R1, R1, #0 ADD R1, R1, #10 AND R2, R2, #0 ; 处理负数 AND R3, R0, #0 ADD R3, R0, #0 BRzp PositiveNum LD R0, MinusSign OUT NOT R3, R3 ADD R3, R3, #1 PositiveNum AND R4, R4, #0 DigitLoop AND R0, R0, #0 ADD R0, R3, #0 JSR DIVIDE_BY_TEN ADD R4, R4, #48 STR R4, R2, #0 ADD R2, R2, #1 ADD R3, R0, #0 BRnp DigitLoop PrintLoop ADD R2, R2, #-1 LDR R0, R2, #0 OUT BRp PrintLoop LD R1, SaveR1 LD R2, SaveR2 LD R3, SaveR3 LD R4, SaveR4 RET ; 辅助除法:R0 = R0/10,R4 = R0%10 DIVIDE_BY_TEN AND R4, R4, #0 DivideLoopTen ADD R0, R0, #-10 BRn DivideDoneTen ADD R4, R4, #1 BRnzp DivideLoopTen DivideDoneTen ADD R0, R0, #10 RET MinusSign .FILL #45 SaveR1 .BLKW 1 SaveR2 .BLKW 1 SaveR3 .BLKW 1 SaveR4 .BLKW 1 NewLine .FILL #10
然后在OPERATION_FINISHED中调用该函数:
OPERATION_FINISHED LEA R0, resultMsg PUTS ADD R0, R4, #0 JSR PrintNumber LD R0, NewLine OUT LEA R0, continue PUTS GETC OUT LD R6, NEG_ONE_TEN ADD R0, R0, R6 BRz STOP_PROGRAM LD R0, NewLine OUT BRnzp ContProgram
内容的提问来源于stack exchange,提问作者Matthew Hamp
相关产品推荐
相关产品推荐

