Recursion 如何在MIPS程序集中编写此代码?
我试图自己学习汇编,但我对如何编写在return语句中多次调用自身的递归函数感到困惑 这是C中的函数:Recursion 如何在MIPS程序集中编写此代码?,recursion,assembly,mips,Recursion,Assembly,Mips,我试图自己学习汇编,但我对如何编写在return语句中多次调用自身的递归函数感到困惑 这是C中的函数: int main() { int a; a = rec3(5); printf("%d", a); return 0; } int recursion(int x) { if (x > 0) { return x + recursion(x-1) + recursion(x-2); } else { ret
int main()
{
int a;
a = rec3(5);
printf("%d", a);
return 0;
}
int recursion(int x) {
if (x > 0) {
return x + recursion(x-1) + recursion(x-2);
}
else {
return 0;
}
}
这就是我到目前为止得到的结果:
.text
main:
li $v0, 5 #Read in an int
syscall
move $a0, $v0 #Move the int to argument
jal Rec #Call Recursion function
move $a0, $v0 #Print the value
li $v0, 1
syscall
li $v0, 10
syscall
Rec: subu $sp, $sp, 8
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
Done: lw $ra, 4($sp)
lw $s0, ($sp)
addu $sp, $sp, 8
jr $ra
我还没有写函数的递归部分,因为我太不知道怎么做了。谁能写出递归部分,让我了解如何解决它?我还想澄清,这不是一个学校项目或类似的东西。我只是想了解如何在MIPS汇编中进行递归,所以我制作了自己的函数。你知道你可以将它转换成这个,对吗
int tmp1 = recursion(x-1);
int tmp2 = recursion(x-2);
return x + tmp1 + tmp2;
如果在return语句中有多个递归调用让您感到困惑,那么这有帮助吗
您发明的第一个临时变量必须保存在第二个函数调用的某个位置(例如,保留调用的寄存器),作为计算该表达式的一部分。就像任何时候你需要一些数据才能在函数调用中生存一样
编译器执行此操作的方式是在函数的开始/结束处保存/恢复一对保留调用的寄存器,如$s0
和$s1
,并在函数中使用它们来执行x
和该临时操作
或者对其进行优化,只在单个寄存器中保存x+递归(x-1)
,因此您只需要该寄存器和第二次函数调用返回后的返回值
当然,优化编译器会将一些递归转换为循环,而不会实际生成递归次数如此之多的程序集。您甚至可以手动将其简化为一个修改过的Fibonacci循环,使用O(n)运行时而不是O(Fib(n)),只需将最后两个序列值保留在寄存器中。这就是如何有效地实现这个函数,但不会教你递归。不幸的是,这个函数是递归不方便的例子,也是实现这个计算最糟糕的方法 (我之所以提到这一点,主要是因为你问我如何在asm中编写这段代码。我会编写与C具有相同可观察结果的asm,应用C标准中的“好像”规则,编译器可以这样做。在ISO C中,递归不算作可观察结果。显然,对于赋值或学习,你实际上不应该这样做rn关于递归。)有人能帮我完成这段代码吗?这不是一个适合这个网站的问题。