📜  mips recursion fibonacci (1)

📅  最后修改于: 2023-12-03 15:17:39.728000             🧑  作者: Mango

MIPS 递归 Fibonacci

Fibonacci 数列指的是:0、1、1、2、3、5、8、13、21、34……,即第 n 个数等于第 n-1 个数和第 n-2 个数的和,其中第 0 个数为 0,第 1 个数为 1。

使用递归方法求解 Fibonacci 数列是一种简单的方法。下面是 MIPS 汇编代码实现。

代码实现
.data
    newline: .asciiz "\n"
    
.text
main:
    addi $s0, $zero, 10    # 求前 10 个数的 Fibonacci 数
    addi $s1, $zero, 0     # 第一个数为 0
    addi $s2, $zero, 1     # 第二个数为 1
    move $a0, $zero        # 参数为 0
    jal fib                # 调用递归函数计算 Fibonacci 数

    li $v0, 10             # 退出程序
    syscall

# $a0 - 参数
fib:
    sub $sp, $sp, 8        # 保存返回地址和 $ra 的值
    sw $ra, 4($sp)
    sw $a0, 0($sp)
    
    li $v0, 0              # 初始化 $v0 为 0
    beq $a0, $zero, fib_return  # 如果参数为 0,返回 0
    beq $a0, 1, fib_return  # 如果参数为 1,返回 1
    
    addi $a0, $a0, -1      # 将参数减 1,递归调用 fib 函数
    jal fib
    move $s3, $v0          # 保存返回值到 $s3
    addi $a0, $a0, 1       # 将参数加 1,再减 1,递归调用 fib 函数
    jal fib
    add $v0, $s3, $v0      # 计算结果
    
fib_return:
    lw $a0, 0($sp)         # 恢复参数
    lw $ra, 4($sp)         # 恢复返回地址
    addi $sp, $sp, 8       # 回收栈空间
    jr $ra                 # 返回
代码说明

这段代码使用递归方法计算 Fibonacci 数列。在 main 函数中,我们从第 0 个数开始,计算前 10 个数的 Fibonacci 数。接着,我们调用 fib 函数,并传入参数 0。

fib 函数中,我们首先保存返回地址和 $ra 的值。接着,如果参数为 0 或 1,我们直接返回相应的值。否则,我们将参数减 1,递归调用 fib 函数,得到第 n-1 个 Fibonacci 数。我们再将参数加 1,并再次减 1,递归调用 fib 函数,得到第 n-2 个 Fibonacci 数。最后,我们将这两个数相加并返回。

需要注意的是,在递归调用 fib 函数之前,我们需要将返回值保存到 $s3 中,否则第二次调用 fib 函数时,第一次调用的返回值会被覆盖。

总结

使用递归方法求解 Fibonacci 数列是一种简单而优美的方法。这个例子充分展示了使用递归的容易实现性和可读性。

该程序中,我们还学到了如何保存和恢复 $ra 的值,以及如何使用 $s 寄存器保存中间结果。这些都是 MIPS 编程中常用的技巧,需要加以掌握。