Mips 递归 Fabonacii 练习

前言

昨天用 misps 汇编写 Fibonacii 递归, 简直恶心的要死。为此有了这篇文章并总结出了一些规律在文末。

c函数原型

int Fibonacii(int n)
{
     if(n == 0)return 1;
     else if(n == 1)return 1;
     return  Fibonacii(n-1)+Fibonacii(n-2);
}

int main()
{
	printf("%d\n", Fibonacii(4));
	return 0;
}

期待结果

0 1 2 3 4 5 6  
1 1 2 3 5 8 13 

Mips 代码

.data

.text

main:

li $v0 5
syscall
addi $a0 $v0 0
jal Fabonacii

addi $a0 $v0 0   #输出计算结果
addi $v0 $zero 1
syscall

li $v0 10
syscall 

Fabonacii:
addi $sp $sp -12 #储存此函数的父亲的参数
sw $ra 8($sp)
sw $a0 4($sp)
sw $t1 0($sp)

li $t0 1 #由于这里的 t0 每次都是1,所以我们不用储存
beq $a0 $zero return_special
beq $a0 $t0 return_special

# Fabonacii(n-1)
li $t1 0
addi $a0 $a0 -1
jal Fabonacii                  
add $t1 $t1 $v0 #保存返回值
addi $a0 $a0 1

# Fabonacii(n-2)
addi $a0 $a0 -2
jal Fabonacii
add $v0 $v0 $t1

lw $t1 0($sp)
lw $a0 4($sp)
lw $ra 8($sp)
addi $sp $sp 12 #储存此函数的父亲的参数
jr $ra #mips中 仅仅有返回的作用, 若要有返回值,将其赋值给 $v0 即可

return_special:  #归的起点,即叶过程
li $v0 1
addi $sp $sp 12 #储存此函数的父亲的参数
jr $ra

错误总结

  1. 将 sw 与 lw 写成了 lb 与sb
  2. 忘记返回的时候将栈清空了

Mips 编写递归的要点(自己总结的)

通过用 Mips 编写递归程序才能总结出一些规律防止出错, 每次写地柜必须问自己这些

1.何时压栈??
   答:在 调用前 (在jal之前)压栈, 
2.何时出栈???
   答:在 所有 jr $ra  前出栈. 
3.何时还原栈中变量???
答: 在 非叶过程返回(jr $ra前, 要注意非叶过程)前 还原变量
4. 保存所有临时变量, main 函数除外(因为main函数没有爹)
  • 4
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值