MIPS程序触发内存地址越界错误,仅krajStringa函数异常,duzinaStringa运行正常
非法内存访问的核心原因
你当前触发的错误根源是系统调用参数匹配错误:
- MIPS 32位架构下,
$v0 = 4对应的系统调用功能是打印以null为终止符的完整字符串,该调用强制要求$a0寄存器存储目标字符串的内存起始地址,而非单个字符的数值。 - 你的代码中通过
lb $a0, 0($t2)将字符串首字符的ASCII编码值加载到了$a0,相当于把ASCII数值当成了可访问的内存地址传给系统调用。比如首字符是数字'0'(ASCII值48),系统就会尝试访问地址0x00000030,这是内核态保留的低地址空间,用户程序无权限访问,直接触发非法内存访问错误。
修正方法
根据你的测试目标调整对应逻辑即可:
- 若测试目的是验证内存访问逻辑、打印字符串的首字符:
- 需要把系统调用编号切换为
$v0 = 11,该编号对应单个字符打印功能,才会读取$a0中存储的字符ASCII值完成打印,修改后的核心逻辑为:
krajStringa: move $t2, $a0 # 保存第一个字符串的起始地址 lb $a0, 0($t2) # 加载首字符的ASCII值 li $v0, 11 # 切换为单字符打印的系统调用 syscall jr $ra - 需要把系统调用编号切换为
- 若测试目的是打印整个字符串:
- 不需要执行
lb加载操作,直接把存在$t2中的字符串起始地址传回$a0,搭配$v0=4的系统调用即可正常运行。
- 不需要执行
代码附带的小问题提醒
你的duzinaStringa长度计算函数虽然能运行,但存在逻辑偏差:
- 循环碰到null终止符跳出时,
$t0的累计值已经是字符串的实际长度,后续额外执行的addi $t0, $t0, -1会让计算结果比真实长度少1,会漏掉字符串的最后一个可打印字符的计数。
内容的提问来源于stack exchange,提问作者makse
相关产品推荐
相关产品推荐

