Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/assembly/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Recursion 如何在MIPS程序集中编写此代码?_Recursion_Assembly_Mips - Fatal编程技术网

Recursion 如何在MIPS程序集中编写此代码?

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

我试图自己学习汇编,但我对如何编写在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 {
        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关于递归。)

有人能帮我完成这段代码吗?这不是一个适合这个网站的问题。