LC-3汇编程序求助:R4无法获取正确的补码数值
LC-3汇编数值转换错误分析与修复
你的程序无法正确将输入的十进制数转换为补码,核心问题出在数值构建逻辑的实现错误,以及分支流程的混乱,以下是具体问题点和修复方案:
核心问题点
1. 错误的乘10逻辑(MULTIPLY_TEN子程序)
程序试图通过MULTIPLY_TEN实现当前值乘10,但逻辑完全错误:
- 你用
R0作为循环计数器,但R0此时存储的是用户输入的字符(ASCII码,比如'2'是x32),这会导致循环执行x31次,而非10次,完全偏离了乘10的目的。 - 循环内的
ADD R1, R1, R2也不对,R2此时没有被正确赋值为当前的R1,无法实现累加乘10。
2. 分支流程混乱(REMAIN_NUM部分)
在读取后续数字时,程序没有先将输入的ASCII字符转换为数字,就直接跳去执行MULTIPLY_TEN,导致数值构建顺序完全错误:
- 读取新字符后,正确流程应该是先判断是否为数字,转换为数值后,再执行
当前值*10 + 新数字,但你的代码跳过了转换步骤,直接进入乘法,导致错误的数值累加。
3. 数字累加逻辑错误(NUM_LOOP)
NUM_LOOP里只是简单将新数字加到R1,没有先将当前值乘10,导致数字是按位相加而非按十进制位构建(比如输入7246会变成7+2+4+6=19,但因为之前的错误乘法,实际得到错误的6567)。
修复后的关键代码调整
以下是修复核心逻辑后的关键部分代码:
; 处理第一个数字 NUM_1 LD R2, HEX_30 NOT R2, R2 ADD R2, R2, #1 ADD R2, R0, R2 ; 将ASCII字符转为数字(0-9) ADD R1, R1, R2 ; R1 = 第一个数字 BR REMAIN_NUM ; 实现R1 = R1 * 10(用左移优化:x10 = x8 + x2,即左移3位+左移1位) MULTIPLY_TEN ADD R2, R1, R1 ; R2 = R1*2 ADD R1, R1, R1 ; R1 *=2 ADD R1, R1, R1 ; R1 *=2(现在R1=R1*8) ADD R1, R1, R2 ; R1 = R1*8 + R1*2 = R1*10 RET ; 回到调用处 ; 处理剩余数字 REMAIN_NUM GETC OUT LD R2, HEX_0A NOT R2, R2 ADD R2, R2, #1 ADD R2, R0, R2 ; 判断是否为换行 BRZ END_LOOP ; 判断是否为有效数字 LD R2, HEX_30 NOT R2, R2 ADD R2, R2, #1 ADD R2, R0, R2 BRN ERROR_LOOP ; 小于'0',错误 LD R2, HEX_39 NOT R2, R2 ADD R2, R2, #1 ADD R2, R0, R2 BRP ERROR_LOOP ; 大于'9',错误 ; 先将当前值乘10 JSR MULTIPLY_TEN ; 将输入字符转为数字并加到当前值 LD R2, HEX_30 NOT R2, R2 ADD R2, R2, #1 ADD R2, R0, R2 ADD R1, R1, R2 ADD R3, R3, #-1 BRP REMAIN_NUM ; 未到最大位数,继续循环 ERROR_LOOP LD R0, errorMessagePtr PUTS BR START_PROG END_LOOP ADD R4, R4, R1 ; 将结果存入R4 ADD R6, R6, #-1 BRZ NOT_VAL ; 如果是负数(R6原先是1),取补码 BR END_OF_PROG NOT_VAL NOT R4, R4 ADD R4, R4, #1 END_OF_PROG LD R0, HEX_0A OUT QUIT HALT
修复说明
- 正确实现乘10:用LC-3的移位操作(左移3位是乘8,左移1位是乘2,相加得到乘10),比循环累加更高效且逻辑正确。
- 调整流程顺序:读取新数字后,先验证有效性,再执行乘10,最后加上新数字,符合十进制数的构建逻辑。
- 修正负数判断分支:将
BRN改为BRZ,因为当R6是1(负数标志)时,ADD R6, R6, #-1结果为0,BRZ会跳去执行取补码操作,逻辑更准确。
内容的提问来源于stack exchange,提问作者henrypham
相关产品推荐
相关产品推荐

