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

MIPS双精度浮点数递归求幂报错:无效程序计数器值0x00000000

问题分析与修复

你的MIPS代码出现invalid program counter value: 0x00000000错误,核心原因是栈帧中存储位置冲突导致返回地址$ra被破坏,同时还有几处栈操作的逻辑错误,以下是具体问题和修复方案:

主要错误点

  • 栈存储位置重叠:在power函数中,sw $ra 8($sp) 和 s.d $f14, 8($sp) 都使用了栈的8($sp)起始地址,4字节的返回地址$ra被8字节的双精度浮点数覆盖,递归返回时jr $ra会跳转到无效的0地址。
  • 栈帧大小未正确对齐:MIPS要求栈必须8字节对齐,原代码分配16字节栈空间,但要保存两个双精度浮点数(各8字节)和一个字(4字节),总大小20字节,需分配24字节来满足对齐要求。
  • 栈恢复操作对应错误:原代码在done标签处恢复寄存器时,读取位置和存储位置不匹配,导致寄存器值错误。

修复后的代码

.data
array1: .double 2.0 2.0 3.0 3.0 4.2 5.0 2.0 0.0 0.0
array2: .word 5 4 2 1 0 2 3 0 10
array_size: .word 9 
newLine: .asciiz "\n"
one: .double 1.0
.text

main:
    la $s1, array1
    la $s2, array2
    lw $s3, array_size # s3 = 9
    
    li $s4, 0
loop: 
    bge $s4, $s3, exit 

    l.d $f14, 0($s1)
    lw $a2, 0($s2)
    
    jal power
    
    li $v0, 3           
    mov.d $f12, $f20   
    syscall             

    # 打印换行
    li $v0, 4
    la $a0, newLine
    syscall

    addi $s1, $s1, 8  
    addi $s2, $s2, 4  
    
    addi $s4, $s4, 1 # index
    
    j loop

power: 
    # 栈对齐到8字节
    andi $sp, $sp, 0xfffffff8 
    # 分配24字节栈空间:存储$f20(8)、$f14(8)、$ra(4) + 4字节填充对齐
    addi $sp, $sp, -24
    s.d $f20, 0($sp)  
    s.d $f14, 8($sp)
    sw $ra, 16($sp)
        
    l.d $f20, one
    beq $a2, $zero, done
    
    addi $a2, $a2, -1
    jal power
    
    # 用当前底数乘以递归返回的结果
    mul.d $f20, $f14, $f20
    
done:
    # 恢复寄存器,对应存储位置
    l.d $f14, 8($sp)
    lw $ra, 16($sp)
    l.d $f20, 0($sp)
    addi $sp, $sp, 24
    jr $ra  
    
exit: 
    li $v0, 10         
    syscall

修复说明

  1. 调整栈帧存储布局:将$ra存储到16($sp),避免和$f14的存储位置重叠,确保返回地址不会被覆盖。
  2. 正确分配栈空间:分配24字节栈空间,满足8字节对齐要求,同时容纳所有需要保存的寄存器。
  3. 匹配栈恢复操作:恢复寄存器时严格对应存储的位置,保证递归前后寄存器值正确。
  4. 添加换行输出:原代码没有换行,添加后输出结果更清晰。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 22:55:31