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

MIPS汇编程序出现invalid program counter value错误求助

问题分析与修复

直接触发invalid program counter value的原因

你的intRead和sum_calc函数中,栈操作顺序完全颠倒:

# 错误顺序
sw $ra, 0($sp)     # 先将$ra存入当前栈指针位置
addi $sp, $sp, -4  # 再下移栈指针

MIPS栈是向下增长的,正确流程应为先分配栈空间(下移栈指针),再将需保存的寄存器存入栈。错误顺序会导致退出函数时,读取到错误内存位置的$ra值,最终jr $ra跳转到无效的0x0地址。

修复后的栈操作代码:

# intRead函数开头修正
intRead:
    addi $sp, $sp, -4  # 先分配4字节栈空间
    sw $ra, 0($sp)     # 再将$ra存入栈中

# sum_calc函数开头修正
sum_calc:
    addi $sp, $sp, -4  # 先分配4字节栈空间
    sw $ra, 0($sp)     # 再将$ra存入栈中

其他代码问题

打印sum的寄存器赋值错误

在sum_print段中,你错误地将$v0(此时是打印整数的syscall号1)传给$a0,导致打印的是1而非计算出的sum:

# 错误代码
li $v0, 1
move $a0, $v0      # 尝试打印sum

修复为:

li $v0, 1
move $a0, $t2      # 将保存sum的$t2传给$a0
syscall

临时寄存器跨函数依赖的风险

你在sum_calc中依赖$t2作为循环终止条件,但$t2属于临时寄存器($t0-$t9),跨函数调用时其值可能被修改,逻辑依赖非常脆弱。建议通过函数参数传递数组元素个数:

  1. 在intRead中将元素个数通过$v0返回:
intRead_exit:
    move $v0, $t2     # 将元素个数存入$v0返回
    lw $ra, 0($sp)
    addi $sp, $sp, 4
    jr $ra  
  1. 在main中将元素个数传入sum_calc的$a0:
jal intRead         # 读取数组,元素个数返回至$v0
move $a0, $v0       # 将元素个数作为参数传入sum_calc

# ...

jal sum_calc       # 计算sum,$a0为元素个数
  1. 修改sum_calc使用$a0作为终止条件:
sum_loop:
    beq $t0, $a0, sum_exit   # 使用传入的参数$a0判断循环终止

规避同类问题的总结

  • 严格遵守栈操作顺序:保存寄存器前先分配栈空间,恢复寄存器后再释放栈空间。
  • 明确寄存器用途:临时寄存器($t0-$t9)无需在函数中保存,跨函数调用时值可能被覆盖;需跨函数保留的值用保存寄存器($s0-$s7),且函数开头保存、结尾恢复。
  • 遵循函数调用规范:用$a0-$a3传递参数,$v0-$v1传递返回值,避免依赖寄存器的隐含约定。
  • 调试优先检查$ra:遇到PC无效错误时,先确认$ra值是否正确,这通常是栈操作错误导致的。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.29 12:34:57