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

LC3访问违例:xFE00与x3200差异及代码适配方案咨询

LC3程序访问违例问题:xFE00解析、报错原因及修复方案

1. xFE00到底是什么?

在LC3的内存布局里,xFE00是系统栈的初始栈顶地址。LC3内存分为用户可自由使用的空间(x0000xDFFF)和操作系统专属的系统空间(xE000xFFFF),xFE00属于后者,是系统用来管理栈帧、保存上下文的核心区域,用户程序无权限直接访问执行。

2. 为什么会触发访问违例?

你的主程序里有个致命错误:

LD R6, top_stack_addr ; 把系统栈顶地址加载到R6
JSRR R6               ; 直接跳转到R6指向的地址执行

JSRR R6会让程序跳到xFE00去执行代码,但这里是受保护的系统区域,既没有你写的子程序逻辑,用户程序也没权限访问,自然就触发访问违例了。

你改成x3200能正常运行,完全是因为x3200是你编写的SUB_GET_STRING_3200子程序的起始地址,跳转到这里才是正确的执行入口。

3. 不修改xFE00的修复方法

作业要求保留top_stack_addr .FILL xFE00,说明这条指令是用来初始化栈指针的(LC3规范里用R6做栈指针),不是让你用来调用子程序的!你要做的就是把错误的调用指令改成正确的:

修正后的主程序代码

.orig x3000
; 初始化栈指针(保留原指令不动)
LD R6, top_stack_addr ; 请勿修改,除备份/恢复外请勿使用R6
LEA R1,CHAR_ARRAY
; 把错误的JSRR R6换成正确的子程序调用
JSR SUB_GET_STRING_3200
LEA R0,CHAR_ARRAY
HALT

; 本地数据
top_stack_addr .FILL xFE00 ; 保持原样
CHAR_ARRAY .BLKW #100
.end

额外的规范优化(建议执行)

你的子程序里定义了BACKUP_R5_3200,但开头没备份R5、结尾也没恢复。R5是你用来存储返回值的寄存器,为了不破坏主程序里R5的原有数据,得补上这两步:

子程序开头新增备份R5:

SUB_GET_STRING_3200
    ST R0, BACKUP_R0_3200
    ST R1, BACKUP_R1_3200
    ST R2, BACKUP_R2_3200
    ST R3, BACKUP_R3_3200
    ST R4, BACKUP_R4_3200
    ST R5, BACKUP_R5_3200  ; 补上备份R5
    ST R6, BACKUP_R6_3200
    ST R7, BACKUP_R7_3200

子程序结尾新增恢复R5:

LD R0, BACKUP_R0_3200
    LD R1, BACKUP_R1_3200
    LD R2, BACKUP_R2_3200
    LD R3, BACKUP_R3_3200
    LD R4, BACKUP_R4_3200
    LD R5, BACKUP_R5_3200  ; 补上恢复R5
    LD R6, BACKUP_R6_3200
    LD R7, BACKUP_R7_3200
    RET

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.14 22:16:31