Assembly MIPS中的递归

Assembly MIPS中的递归,assembly,recursion,mips,Assembly,Recursion,Mips,我想在汇编中为MIPS实现一个递归程序。更具体地说,我想实现众所周知的斐波那契函数 以下是C语言的实现: int fib(int n) { if(n<2) return 1; return fib(n-1)+fib(n-2); } intfib(intn){ 如果(n将你的C函数编译成一个对象文件并查看 objdump -d fib.o 可能是您的起点。提示-考虑堆栈 顺便说一句,就复杂性(时间和空间)而言,递归是一个非常糟糕的解决方案。一个循环和两个变

我想在汇编中为MIPS实现一个递归程序。更具体地说,我想实现众所周知的斐波那契函数

以下是C语言的实现:

int fib(int n) {
    if(n<2)
        return 1;
    return fib(n-1)+fib(n-2);
}
intfib(intn){

如果(n将你的C函数编译成一个对象文件并查看

objdump -d fib.o

可能是您的起点。

提示-考虑堆栈


顺便说一句,就复杂性(时间和空间)而言,递归是一个非常糟糕的解决方案。一个循环和两个变量会更好。

-Load
n-1
$a0

-使用
jal
指令递归调用
fib

-从
$v0
寄存器获取结果

-将
n-2
加载到
$a0

-使用
jal
指令递归调用
fib

-从
$v0
寄存器获取结果

然后,有一个
addu
指令

哦,是的,您必须使用分支检查
if
,但这与递归无关

如果您需要帮助,编译器是您的朋友

$gcc-c-g纤维c

$objdump-S fib.o

但是


将更清晰。

以下是在MIPS汇编中执行递归阶乘函数的代码。将其更改为Fibonacci将留给读者作为练习。(注意:此代码中没有优化延迟槽,因为它是为可读性而设计的。)


闻起来像是家庭作业不,这不是家庭作业。只是一个练习。你是对的,我需要使用堆栈。我知道这是一个糟糕的解决方案。我只想在MIPS中练习递归。你看到C编译器可以对一段无辜的代码做些什么吗?你可以在gcc-C fib.C输出上使用objdump-s。这会更清楚
-mrnames
在t中被删除4.0分支。
-fverbose asm
也很有用。
$gcc -S -mrnames fib.c -o fib.s
# int fact(int n)
fact:
    subu    sp, sp, 32  # Allocate a 32-byte stack frame
    sw  ra, 20(sp)  # Save Return Address
    sw  fp, 16(sp)  # Save old frame pointer
    addiu   fp, sp, 28  # Setup new frame pointer
    sw  a0,  0(fp)  # Save argument (n) to stack

    lw  v0, 0(fp)   # Load n into v0
    bgtz    v0, L2      # if n > 0 jump to rest of the function
    li  v0, 1       # n==1, return 1
    j   L1      # jump to frame clean-up code

L2:
    lw  v1, 0(fp)   # Load n into v1
    subu    v0, v1, 1   # Compute n-1
    move    a0, v0      # Move n-1 into first argument
    jal fact        # Recursive call

    lw  v1, 0(fp)   # Load n into v1
    mul v0, v0, v1  # Compute fact(n-1) * n

    #Result is in v0, so clean up the stack and return
L1:
    lw  ra, 20(sp)  # Restore return address
    lw  fp, 16(sp)  # Restore frame pointer
    addiu   sp, sp, 32  # Pop stack
    jr  ra      # return
    .end    fact