使用堆栈指针递归斐波那契序列

时间:2015-08-18 19:39:28

标签: assembly recursion stack mips

我正在攻读计算机系统论坛,我们希望能够很好地掌握递归和某些编程问题,使用运行时堆栈传递所有参数,返回结果主程序并堆叠子程序用于保护主程序的所有变量。

我为实践写作的程序递归地计算斐波纳契数列。我理解子程序如何使用堆栈从主程序接收参数/参数,但我很难理解它将如何使用堆栈作为将结果返回主程序的方法,以及何时/如何堆叠所有变量以保护主程序。另外,我很难理解如何实现递归部分。

我真的在寻找有关理解堆栈指针的指针,何时/如何使用它,如何实现递归,以及因此,我的代码中的错误和一般指针我的MIPS编码。谢谢!以下是我到目前为止:

.data
prompt: .ascii "This program calculates Fibonacci sequence. Enter non-negative number:"
result: .asciiz "F="
newline: .asciiz "\n"

.text
.globl main #defining starting point
main:

li $v0, 4   #print string
la $a0, prompt
syscall

li $v0, 5   #read in int
syscall

move $t0, $v0   #putting int into temporary register

move $a0, $t0   #put int as first argument
subi $sp, $sp, 8 #setting up stack
sw $zero, 4($sp)  # for return
sw $a0, 0($sp)    #push int onto stack
jal fibonacci

lw $t0, -4($sp) #get result from fibonacci

li $v0, 4   #print F=
la $a0, result
syscall

li $v0, 1
move $a0, $t0
syscall

li $v0, 4
la $a0, newline
syscall

li $v0, 10
syscall

fibonacci:
lw $v0, 4($sp) #load parameters
lw $a0, 0($sp)
beqz $a0, zero  #if n =0 return 0
beq $a0, $1, one # if n=1 return 1

#calling fib(n-1)
subi $sp, $sp, 4
sw $ra, 0($sp) #push return address onto stack

sub $a0, $a0, 1 #n-1
subi $sp, $sp, 8
sw $zero, 4($sp)
sw $a0, 0($sp)   #pushing n-1 onto stack
jal fibonacci    #fib(n-1)

lw $v0, -4($sp) #get result of fibonacci
add $a0, $a0, 1  #increment back our value

lw $ra, 0($sp) #restoring return address from stack
lw $a0, 4($sp) #protect main program by putting stuff back
sw $v0, 8($sp) #put result on stack

#calling fib(n-2)
subi $sp, $sp, 4
sw $ra, 0($sp)
sub $a0, $a0, 2 #n-2
subi $sp, $sp, 8
sw $zero, 4($sp)   #pushing n-2 onto stack
sw $a0, 0($sp)
jal fibonacci

lw $v0, -4($sp)
addi $a0, $a0, 2
lw $ra, 0($sp)  #restoring return address from stack 
lw $a0, 4($sp)  #protect main program by puttting stuff back
sw $v0, 8($sp)  #put result on stack

lw $s7, 0($sp)  #pop return value from stack (from f(n-1)
add $v0, $v0, $s7  #f(n-2) +f(n-1)
addi $sp, $sp, 12
jr $ra 


zero:
li $v0, 0
lw $ra, 0($sp)      # Get return address
lw $a0, 4($sp)      # Protect main program by putting stuff back
sw $v0, 8($sp)      # Put result on stack
addi $sp, $sp, 12
jr $ra

one:
li $v0, 1
lw $ra, 0($sp)      # Get return address
lw $a0, 4($sp)      # Protect main program by putting stuff back
sw $v0, 8($sp)      # Put result on stack
addi $sp, $sp, 12
jr $ra    

0 个答案:

没有答案