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

在MARS中调试“invalid program counter value: 0x00000000”错误

问题分析与修复方案

错误原因

  • 违反MIPS调用规范:使用被调用者保存寄存器$s0时未提前压栈保存,返回前也未恢复,导致调用者(main)的寄存器状态被破坏,引发程序计数器(PC)异常。
  • 最大值计算逻辑错误:调用getLarger前未正确设置输入参数,且第二次调用后错误地将旧值赋值给$v0,导致最大值结果错误。
  • 平均值计算错误:div指令的商存储在LO专用寄存器中,直接使用$t4获取结果无效,需通过mflo指令读取。
  • 未满足作业栈存储要求:使用临时寄存器$t0-$t3保存参数,而非题目要求的栈存储,不符合作业规范。

修复后的代码

.data

.text
.globl main

# Subprogram getLarger($a0, $a1)
getLarger:
    # $a0 = arg1, $a1 = arg2
    move $v0, $a0          # 默认$a0为较大值
    bgt $a1, $a0, greater_than  # $a1更大则跳转
    j end_getLarger
    nop

greater_than:
    move $v0, $a1

end_getLarger:
    jr $ra
    nop

# Subprogram largestAndAverage($a0, $a1, $a2, $a3)
largestAndAverage:
    # 函数序言:分配栈空间,保存被调用者寄存器和参数
    addi $sp, $sp, -20     # 栈空间:4个参数(16字节) + $s0(4字节)
    sw $s0, 16($sp)        # 保存$s0到栈
    sw $a0, 12($sp)        # 保存var0到栈
    sw $a1, 8($sp)         # 保存var1到栈
    sw $a2, 4($sp)         # 保存var2到栈
    sw $a3, 0($sp)         # 保存var3到栈

    # 计算最大值:依次比较所有参数
    jal getLarger          # 比较$a0和$a1,结果存$v0
    move $s0, $v0          # $s0 = max(a0,a1)
    move $a0, $s0
    lw $a1, 4($sp)         # 从栈取var2
    jal getLarger          # 比较max(a0,a1)和a2
    move $s0, $v0          # $s0 = max(max(a0,a1),a2)
    move $a0, $s0
    lw $a1, 0($sp)         # 从栈取var3
    jal getLarger          # 比较当前最大值和a3
    move $v0, $v0          # $v0 = 最终最大值

    # 计算平均值:从栈读取参数求和
    lw $t0, 12($sp)
    lw $t1, 8($sp)
    lw $t2, 4($sp)
    lw $t3, 0($sp)
    add $t4, $t0, $t1
    add $t4, $t4, $t2
    add $t4, $t4, $t3
    li $t5, 4
    div $t4, $t5
    mflo $v1               # 从LO寄存器读取商作为平均值

    # 函数尾声:恢复寄存器,释放栈空间
    lw $s0, 16($sp)
    addi $sp, $sp, 20
    jr $ra
    nop

# Main program
main:
    # 传入参数 2, 5, 8, 11
    li $a0, 2
    li $a1, 5
    li $a2, 8
    li $a3, 11

    jal largestAndAverage

    # 退出程序
    li $v0, 10
    syscall

关键修复点说明

  1. 栈存储参数:严格按照作业要求将$a0-$a3全部压入栈中,后续计算从栈读取参数,避免getLarger修改$a0/$a1导致参数丢失。
  2. 寄存器合规使用:使用$s0前压栈保存其值,函数返回前恢复,符合MIPS被调用者保存寄存器的规范,避免破坏调用者状态。
  3. 最大值逻辑修正:每次调用getLarger前正确设置$a0和$a1参数,确保依次比较所有四个输入值,最终将正确最大值存入$v0。
  4. 平均值计算修正:使用mflo指令读取div指令生成的商,确保平均值结果正确。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.05 12:52:50