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
修复说明
- 调整栈帧存储布局:将$ra存储到
16($sp),避免和$f14的存储位置重叠,确保返回地址不会被覆盖。 - 正确分配栈空间:分配24字节栈空间,满足8字节对齐要求,同时容纳所有需要保存的寄存器。
- 匹配栈恢复操作:恢复寄存器时严格对应存储的位置,保证递归前后寄存器值正确。
- 添加换行输出:原代码没有换行,添加后输出结果更清晰。
内容的提问来源于stack exchange,提问作者Luke
相关产品推荐
相关产品推荐

