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

LC3汇编GetString子程序返回异常及字符存储错误求助

LC3汇编GetString子程序调试问题

问题现象

  • 返回异常:执行RET指令后未返回主程序,反而跳回ADD R1, R0, #-10指令行
  • 字符串存储错误:字符写入位置混乱,具体错误:
    • 位置1的字符错误:' '应为'H'(出现2次)
    • 位置2的字符错误:' '应为'H'
    • 位置1的字符错误:' '应为'�'
    • 位置3的字符错误:' '应为'�'
    • 位置2的字符错误:' '应为'V'
    • 位置2的字符错误:' '应为'S'
    • 位置2的字符错误:' '应为'n'
    • 位置1的字符错误:' '应为'b'

原始代码

GETSTRING
;Save ALL registers that you change except for return Registers.
ST R1, GS_R1    ;Save R1 as an example.
ST R7, GS_R7

;.... PUT YOUR CODE HERE ....

ADD R1, R0, #0

GS_TOP

JSR GETLETTER

ADD R1, R0, #-10

BRZ GS_DONE

STR R0, R1, #0

ADD R1, R1, #1

BRNZP GS_TOP

GS_DONE
ST R1, #0

;Registers registers you used.
LD R1, GS_R1    ;Restore R1
LD R7, GS_R7
RET ;This subroutine should ONLY have one return here.

;Storage for GETSTRING.
;All .fill, .stringz, .blkw labels used in this subroutine should go here.
GS_R1   .fill 0     ;Storage location for R1 in GETSTRING
GS_R7   .fill 0
;------------------------------------------------------------------------------
;END OF GETSTRING
;------------------------------------------------------------------------------

错误根源分析

  1. 字符串指针被破坏:
    代码中用ADD R1, R0, #-10判断输入是否为回车键(ASCII 10),但R1是存储字符串缓冲区指针的寄存器,这一步直接覆盖了指针值,导致后续STR R0, R1, #0把字符写入错误的内存地址,这是字符存储混乱的核心原因。

  2. 返回逻辑被破坏:
    GS_DONE处的ST R1, #0指令会把R1的值存入当前PC偏移0的位置,直接覆盖了后续的LD R1, GS_R1指令,导致寄存器恢复逻辑失效,最终RET使用了错误的返回地址。

  3. 缺少字符串终止符:
    输入结束后未给字符串添加ASCII 0终止符,不符合LC3字符串规范。

修复后的代码

GETSTRING
; 保存所有会修改的寄存器(除返回寄存器)
ST R1, GS_R1    
ST R7, GS_R7    ; 保存主程序传入的返回地址

; 初始化字符串缓冲区指针:R0为传入的缓冲区起始地址
ADD R1, R0, #0

GS_TOP
JSR GETLETTER   ; 调用子例程获取字符,R7会被修改为当前指令的下一条地址

; 用临时寄存器R2判断是否为回车键(ASCII 10),避免破坏R1指针
ADD R2, R0, #-10
BRZ GS_DONE

; 将获取到的字符存入缓冲区,指针自增1
STR R0, R1, #0
ADD R1, R1, #1

BRNZP GS_TOP

GS_DONE
; 在字符串末尾添加ASCII 0终止符
AND R0, R0, #0
STR R0, R1, #0

; 恢复寄存器
LD R1, GS_R1    
LD R7, GS_R7    ; 恢复主程序的返回地址
RET

; 子程序存储区
GS_R1   .fill 0     
GS_R7   .fill 0
;------------------------------------------------------------------------------
;END OF GETSTRING
;------------------------------------------------------------------------------

修复说明

  • 改用R2寄存器进行回车键判断,保留R1作为字符串缓冲区指针,确保字符写入正确地址。
  • 移除GS_DONE处错误的ST R1, #0指令,替换为写入字符串终止符的逻辑。
  • 保留R7的提前保存,确保最终RET能正确跳回主程序的调用位置。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.25 06:39:22