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

LC3程序为何无法执行到RET或HALT指令?

问题分析与解决方案

核心问题点

  1. 寄存器未完整恢复:GETSTR子程序中保存了R4寄存器,但返回前仅恢复了R2、R3,未恢复R4,导致寄存器值污染,可能引发后续执行异常。
  2. 字符串无终止符:输入ENTER后未在字符串末尾写入ASCII 0(null字符),PUTS会持续输出内存内容直到遇到null,引发无限输出或异常循环。
  3. 数据布局冲突:原代码用.stringz初始化STR1,但注释明确要求用.blkw预留存储空间,多余的'z'会导致PUTS输出无关内容。

修改后的代码

.orig x3000
MAIN
    LEA R0, STR1 ; R0指向字符串存储区
    JSR GETSTR   ; 获取用户输入的字符串
    PUTS         ; 打印字符串
    HALT

; 字符串存储区:预留50个单元,用于存储输入的字符串
STR1 .blkw 50   ; 替换原.stringz,避免多余字符干扰

GETSTR
    ; 保存用到的寄存器
    ST R2, GS_SR2
    ST R3, GS_SR3
    ST R4, GS_SR4

    LD R4, GS_LR4 ; R4 = -10,用于判断是否为ENTER(ASCII 10)
    ADD R2, R0, #0 ; R2指向当前要存储字符的位置

GSTOP
    GETC ; 获取用户输入的字符
    ADD R3, R0, R4 ; 计算输入字符 + (-10),若为ENTER则结果为0
    BRZ GSEND ; 是ENTER则跳转到结束处理

    STR R0, R2, #0 ; 将字符存入字符串存储区
    OUT ; 回显字符

    ADD R2, R2, #1 ; 移动到下一个存储位置
    BRNZP GSTOP ; 继续获取字符

GSEND
    ; 在字符串末尾添加null终止符,确保PUTS能正常停止
    AND R0, R0, #0 ; R0 = 0(ASCII null)
    STR R0, R2, #0 ; 存入当前位置

    ; 恢复所有保存的寄存器
    LD R2, GS_SR2
    LD R3, GS_SR3
    LD R4, GS_SR4 ; 新增恢复R4

    RET ; 返回MAIN

; 寄存器保存区
GS_SR2  .fill 0
GS_SR3  .fill 0
GS_SR4  .fill 0

GS_LR4  .fill -10 ; 用于判断ENTER的常量

.end

修改说明

  • 替换STR1为.blkw 50:移除原.stringz的大量'z',改用干净的预留存储空间,避免PUTS输出无关内容。
  • 添加null终止符:在GSEND段中写入ASCII 0,确保PUTS输出到字符串末尾后停止。
  • 恢复R4寄存器:补充LD R4, GS_SR4指令,完整恢复所有保存的寄存器,避免寄存器值异常影响后续执行。

修改后,按下ENTER时代码会正常跳转到GSEND,添加终止符后返回MAIN,执行PUTS打印输入内容后停机,符合预期。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 01:30:57