MIPS汇编程序报错求助:筛选大于0且能被4整除的数时地址越界
MIPS汇编程序地址越界错误排查
我编写了一段使用blt指令的MIPS汇编程序,需求是打印所有大于0且能被4整除的数,但运行时出现如下报错:
(1).zip line 32: Runtime exception at 0x0040000c: address out of range 0x00000000
以下是我的代码:
num1: .word -8 , num3 num2: .word 1998 , 0 num3: .word -9034 , num5 num4: .word -100 , num2 num5: .word 1972, num4 ###############################code segment ########################################################### .text .globl main main: #main program entry #load num1 from memory to $t0 (pesudo- instr) secod: la $t0,num1 li $a0,0 Secondloop: lw $t1, 0($t0) blt $t1 , $zero , notCount lw $t0, 4($t0) andi $t2 , $t1 , 3 beq $t2, $zero, theSecondCheck j Secondloop notCount: lw $t0, 4($t0) beq $t0,$zero,secondPrint j Secondloop theSecondCheck: beq $t2,$zero,sum j Secondloop sum: add $a0, $t1, $a0 j Secondloop secondPrint: #print the result li $v0,1 syscall thirdLoop: la $t0,num1 lw $t1, 0($t0) lw $t0, 4($t0) beq $t0,$zero,continuePrint li $v0,11 bge $t1,$zero,printFourBase li $a0, '-' syscall sub $t1,$zero,$t1 printFourBase: li $t3,16 li $v0,1 continuePrint: rol $t1,$t1,2 andi $a0,$t1,3 syscall addi $t3,$t3,-1 bne $t3,$zero,Exit j continuePrint Exit: li $v0,10
错误原因分析
1. 链表遍历的空指针访问
你的数据结构是链表,最后一个节点num2的后继地址是0。当遍历到num2时:
- 在
notCount或Secondloop中执行lw $t0,4($t0),会把0加载到$t0寄存器。 - 回到
Secondloop后执行lw $t1,0($t0),等同于从地址0x00000000读取数据,这是MIPS架构中不允许的无效地址,直接触发地址越界错误。 - 核心问题:加载后继地址为
0后未立即终止循环,反而继续用该无效地址访问内存。
2. 执行流程的逻辑冗余与顺序错误
- 在
Secondloop中,处理正数时先更新节点指针再判断整除性,若新指针是0,后续循环仍会访问无效地址。 theSecondCheck中的beq $t2,$zero,sum完全多余,因为前面已经通过beq $t2,$zero,theSecondCheck跳转至此,说明$t2必然为0,无需重复判断。
3. 打印模块的逻辑混乱
thirdLoop未被正确调用(secondPrint执行syscall后会直接进入该模块),且内部跳转逻辑错误:bne $t3,$zero,Exit会在第一次循环就跳转到退出流程,完全无法实现打印功能;同时整个模块未筛选“大于0且能被4整除”的数,不符合需求。
修正建议
修复链表遍历终止逻辑:
每次加载后继节点地址后,立即判断是否为0,若是则终止循环,避免访问无效地址。例如调整notCount:notCount: lw $t0, 4($t0) beq $t0,$zero,secondPrint j Secondloop同时在
Secondloop处理完当前节点后,也要检查$t0是否为0再决定是否继续循环。调整
Secondloop执行顺序:
先判断当前数是否符合条件(大于0且能被4整除),再加载后继节点地址,避免提前更新指针导致的错误:Secondloop: lw $t1, 0($t0) blt $t1 , $zero , notCount andi $t2 , $t1 , 3 beq $t2, $zero, sum # 不符合条件,加载下一个节点 lw $t0, 4($t0) bne $t0,$zero,Secondloop j secondPrint重构打印模块:
确保打印模块只处理符合条件的数,并且梳理跳转逻辑保证流程正确,比如在遍历过程中直接打印符合条件的数,或者在secondPrint后正确调用打印模块。
内容的提问来源于stack exchange,提问作者Ron Tzobel
相关产品推荐
相关产品推荐

