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

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整除”的数,不符合需求。

修正建议

  1. 修复链表遍历终止逻辑:
    每次加载后继节点地址后,立即判断是否为0,若是则终止循环,避免访问无效地址。例如调整notCount:

    notCount:     
        lw $t0, 4($t0) 
        beq $t0,$zero,secondPrint  
        j Secondloop
    

    同时在Secondloop处理完当前节点后,也要检查$t0是否为0再决定是否继续循环。

  2. 调整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
    
  3. 重构打印模块:
    确保打印模块只处理符合条件的数,并且梳理跳转逻辑保证流程正确,比如在遍历过程中直接打印符合条件的数,或者在secondPrint后正确调用打印模块。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.22 10:54:14