LC3素数判断代码报“无效TRAP执行”错误,求问题原因
LC3素数判断代码"invalid TRAP executed"报错分析与修复
报错根源
你代码里写的PUTS不是LC3的有效机器指令——LC3中要输出字符串,必须用TRAP x22来调用系统提供的PUTS功能。WebLC3模拟器不认直接写的PUTS,所以触发了无效TRAP错误。
代码里的其他问题
除了TRAP指令写错,还有几个逻辑漏洞:
- 负数处理不当:输入负数时,代码会跳去查素数数组,但数组里根本没有负数对应的项,会直接访问非法内存地址,应该直接把负数判定为非素数。
- 数组越界风险:如果输入的数字超过你定义的数组长度(比如输入6),会读取数组后面的字符串或数据,导致逻辑混乱。
- 冗余代码:
ADD R2, R2, #1这行完全没用,后续代码根本没用到R2。
修复后的完整代码
.ORIG x3000 LD R0, INPUT_NUMBER ; 加载测试数字到R0 AND R2, R0, #0 ADD R2, R0, #-1 BRz IS_NOT_PRIME ; 输入是1,非素数 ADD R2, R0, #0 BRn IS_NOT_PRIME ; 输入是负数,直接判定非素数 ADD R2, R0, #-2 BRn IS_NOT_PRIME ; 输入是0,非素数 CONTINUE_CHECK: ; 检查输入是否超出数组支持的最大数字 LD R2, MAX_PRIME_INDEX NOT R2, R2 ADD R2, R2, #1 ; 转换成-5 ADD R2, R0, R2 BRp IS_NOT_PRIME ; 输入>5,超出数组范围,判定非素数(要支持更大数字就扩展数组) LEA R3, PRIME_ARRAY ; 加载素数数组的起始地址 ADD R3, R3, R0 ; 计算要查询的索引地址 LDR R4, R3, #0 ; 读取对应位置的标记值 BRz IS_NOT_PRIME ; 标记为0,非素数 ; 判定为素数的处理 LD R0, PRIME_VAL ; R0存1表示素数 LEA R1, PRIME_MSG ; 加载素数提示字符串的地址 TRAP x22 ; 调用系统PUTS输出字符串 BR FINISH IS_NOT_PRIME: AND R0, R0, #0 ; R0存0表示非素数 LEA R1, NOT_PRIME_MSG ; 加载非素数提示字符串的地址 TRAP x22 ; 调用系统PUTS输出字符串 FINISH: TRAP x25 ; 调用系统HALT终止程序(部分模拟器对HALT指令支持差,用这个更稳) ; 数据定义 INPUT_NUMBER .FILL #3 ; 测试数字,改这里换测试值 PRIME_VAL .FILL #1 ; 素数的标记值 NOT_PRIME_MSG .STRINGZ "0\n" ; 非素数时输出的内容 PRIME_MSG .STRINGZ "1\n" ; 素数时输出的内容 MAX_PRIME_INDEX .FILL #5 ; 数组支持的最大数字索引 PRIME_ARRAY .FILL #0 ; 0:非素数 .FILL #0 ; 1:非素数 .FILL #1 ; 2:素数 .FILL #1 ; 3:素数 .FILL #0 ; 4:非素数 .FILL #1 ; 5:素数 ; 需要支持更大数字的话,在这里继续添加.FILL定义 .END
修复要点说明
- 替换PUTS为TRAP x22:这是LC3标准的系统调用方式,所有LC3模拟器都能正确识别。
- 完善边界判断:
- 直接把负数、0、1判定为非素数
- 增加数组范围检查,避免越界访问乱码内存
- 清理冗余代码:删掉没用的
ADD R2, R2, #1 - 可选替换HALT为TRAP x25:有些模拟器对原生HALT指令支持不佳,用TRAP x25调用系统终止功能兼容性更好。
内容的提问来源于stack exchange,提问作者Frederik Andersen
相关产品推荐
相关产品推荐

