C++转MIPS代码输出异常求助:无法得到正确结果25、109、321
C++转MIPS代码错误排查与修正
问题描述
我是一名大学生,作业要求将下方C++代码转换为MIPS代码,但转换后的代码无法输出正确结果(预期输出25、109、321),距离截止只剩5小时,请求帮忙排查错误并提供正确代码,使用Mars4_5.jar编写.asm格式代码。
原C++代码
#include <iostream> using namespace std; int poly(int); int pow(int, int); int main() { int i; int result; for (i=2; i<=4; i++) { result = poly(i); cout << result << endl; } } int poly(int arg) { int temp1, result; temp1 = pow(arg, 4); result = pow(arg, 3); result = temp1 + result + 1; return result; } int pow(int arg0, int arg1) { int product = 1; for (int i=0; i<arg1; i++) { product *= arg0; } return product; }
错误的MIPS代码
.data newline: .asciiz "\n" .text globl main main: li $t0, 2 li $t1, 4 loop: bgt $t0, $t1, end move $a0, $t0 jal poly move $a0, $v0 li $v0, 1 syscall li $v0, 4 la $a0, newline syscall addi $t0, $t0, 1 j loop end: li $v0, 10 syscall poly: addi $sp, $sp, -12 sw $ra, 8($sp) sw $s0, 4($sp) move $s0, $a0 move $a0, $s0 li $a1, 4 jal pow move $s1, $v0 move $a0, $s0 li $a1, 3 jal pow add $v0, $s1, $v0 addi $v0, $v0, 1 lw $ra, 8($sp) lw $s0, 4($sp) addi $sp, $sp, 12 jr $ra pow: addi $sp, $sp, -8 sw $ra, 4($sp) sw $s0, 0($sp) li $s0, 1 loop_pow: bge $a1, $zero, exit_pow mul $s0, $s0, $a0 addi $a1, $a1, -1 j loop_pow exit_pow: move $v0, $s0 lw $ra, 4($sp) lw $s0, 0($sp) addi $sp, $sp, 8 jr $ra
错误原因分析
- pow函数循环逻辑错误:原C++中
pow函数循环执行arg1次乘法,但当前MIPS代码用bge $a1, $zero, exit_pow作为循环退出条件,初始$a1为4或3(均大于0),会直接退出循环,完全不执行乘法操作,返回值始终为1,导致计算结果错误。 - poly函数栈操作遗漏:
poly函数中使用了$s1寄存器存储pow(arg,4)的结果,但未将$s1保存到栈中,违反MIPS调用规范,后续调用pow(arg,3)时会覆盖$s1的值,破坏之前的计算结果。 - 全局符号拼写错误:原代码中
globl main应为.globl main,不符合MIPS汇编语法规范。
修正后的MIPS代码
.data newline: .asciiz "\n" .text .globl main main: li $t0, 2 li $t1, 4 loop: bgt $t0, $t1, end move $a0, $t0 jal poly # 输出计算结果 move $a0, $v0 li $v0, 1 syscall # 输出换行符 li $v0, 4 la $a0, newline syscall addi $t0, $t0, 1 j loop end: li $v0, 10 syscall poly: addi $sp, $sp, -16 # 扩展栈空间,新增$s1的保存位置 sw $ra, 12($sp) sw $s0, 8($sp) sw $s1, 4($sp) move $s0, $a0 # 调用pow(arg,4)并保存结果 move $a0, $s0 li $a1, 4 jal pow move $s1, $v0 # 调用pow(arg,3) move $a0, $s0 li $a1, 3 jal pow # 计算最终结果:temp1 + result + 1 add $v0, $s1, $v0 addi $v0, $v0, 1 # 恢复栈中保存的寄存器 lw $ra, 12($sp) lw $s0, 8($sp) lw $s1, 4($sp) addi $sp, $sp, 16 jr $ra pow: addi $sp, $sp, -8 sw $ra, 4($sp) sw $s0, 0($sp) li $s0, 1 loop_pow: beq $a1, $zero, exit_pow # 次数为0时退出循环,确保执行arg1次乘法 mul $s0, $s0, $a0 addi $a1, $a1, -1 j loop_pow exit_pow: move $v0, $s0 lw $ra, 4($sp) lw $s0, 0($sp) addi $sp, $sp, 8 jr $ra
验证说明
修正后的代码运行后会输出预期结果:
- 当i=2时:
2^4 + 2^3 +1 = 16+8+1=25 - 当i=3时:
3^4 +3^3 +1=81+27+1=109 - 当i=4时:
4^4 +4^3 +1=256+64+1=321
内容的提问来源于stack exchange,提问作者Lion98
相关产品推荐
相关产品推荐

