MIPS——递归调用

嵌套过程

不调用其他过程的过程称为叶过程(leaf procedure)。如果所有过程都是叶过程,那么情况就很简单。但是某个过程可以调用其他过程,甚至调用的是自身的“克隆”。在调用非叶过程时使用寄存器需要十分小心。

例如,假设主程序将参数3存入寄存器a0,然后使用jal A调用过程A。再假设过程A通过jal B调用过程B,参数为7,同样存入a0。由于A尚未结束任务,所以在寄存器a0的使用上存在冲突。同样,在寄存器ra保存的返回地址也存在冲突,因为它现在保存着B的返回值。

我们必须采取措施阻止这类问题发生:

一个解决方法是将其他所有必须保存的寄存器压栈,就像将保存寄存器压栈一样。调用者将所有调用后还需的参数寄存器(a1~a3)或临时寄存器(t0~t9)压栈。被调用者将返回地址寄存器(ra)和被调用者使用的保存寄存器(a0~a7)都压栈。栈指针 sp 随这栈中的寄存器个数调整。到返回时,寄存器会从存储器中恢复,栈指针也会随着重新调整。

有关指令

1     jal  function   #set $ra to Program Counter(PC),then jump to statement at target addres

C语言代码

 1 #include<stdio.h>
 2 
 3 int factorial(int n);
 4 
 5 int main()
 6 {
 7     int n;
 8</
  • 4
    点赞
  • 24
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
好的,以下是 MIPS 语言递归实现斐波那契数列的输出的代码示例: ``` .data result: .word 0 # 用来存储斐波那契数列的结果 .text .globl main main: # 调用递归函数计算斐波那契数列 addi $a0, $zero, 10 # 计算斐波那契数列的前10项 jal fibonacci # 输出结果 li $v0, 1 lw $a0, result syscall # 退出程序 li $v0, 10 syscall # 递归函数 fibonacci # 参数 $a0:需要计算的斐波那契数列项数 # 返回值:$v0 中存储了计算结果 fibonacci: addi $sp, $sp, -8 # 分配栈空间 sw $ra, 0($sp) # 保存返回地址 # 判断是否计算到了第1项或第2项 li $t0, 1 blt $a0, $t0, base_case beq $a0, $t0, base_case # 递归计算前两项的值 addi $a0, $a0, -1 jal fibonacci sw $v0, 0($sp) # 保存计算结果 addi $a0, $a0, -1 jal fibonacci lw $t1, 0($sp) # 加载上一次计算的结果 add $v0, $v0, $t1 # 计算当前项的值 sw $v0, result # 保存计算结果 lw $ra, 0($sp) # 恢复返回地址 addi $sp, $sp, 8 # 释放栈空间 jr $ra # 返回计算结果 # 递归基准情况处理函数 base_case # 参数 $a0:需要计算的斐波那契数列项数 # 返回值:$v0 中存储了计算结果 base_case: li $v0, 1 lw $ra, 0($sp) # 恢复返回地址 addi $sp, $sp, 8 # 释放栈空间 jr $ra # 返回计算结果 ``` 此代码使用递归法实现斐波那契数列的计算,并将结果存储在 `.data` 段中的 `result` 变量中,最后输出第 10 项的值。在 `fibonacci` 函数中,如果需要计算的斐波那契数列项数小于等于 2,就会转到 `base_case` 函数进行计算。否则,递归计算前两项的值,并用它们计算当前项的值。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值