You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

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

修复说明

  1. 正确实现乘10:用LC-3的移位操作(左移3位是乘8,左移1位是乘2,相加得到乘10),比循环累加更高效且逻辑正确。
  2. 调整流程顺序:读取新数字后,先验证有效性,再执行乘10,最后加上新数字,符合十进制数的构建逻辑。
  3. 修正负数判断分支:将BRN改为BRZ,因为当R6是1(负数标志)时,ADD R6, R6, #-1结果为0,BRZ会跳去执行取补码操作,逻辑更准确。

内容的提问来源于stack exchange,提问作者henrypham

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 13:01:08