简体   繁体   中英

MIPS Assembly - Fibonacci Registers

I am writing a recursive Fib function for MIPS. I need help understanding the $a0 register. I want to call the function with n-1, and n-2, but after you call it with n-1, the $a0 register changes. So say you want fib(2), even though after it jal's, it should keep the original value of 2, however it is still 1 from the n-1 call before. And 1-2 = -1, which makes it endless. I have tried loading $a0 before I call n-2, but that also throws everything off. Here is the code. Thank you

# switch to the Text segment
.text
# the program is defined here

.globl  main
main:


add $a0, $zero, 2
add $a1, $zero, 0
jal fib

j print_end


fib:
addi    $sp, $sp, -12
sw  $ra, 0($sp)
sw  $a0, 4($sp)
sw  $a1, 8($sp)

addi    $t5, $zero, 1
beq $a0, $zero, end_fib
beq $a0, $t5, end_fib
j   not_base
end_fib:
addi    $v0, $a0, 0     #base return 0 or 1
addi    $sp, $sp, 12
jr  $ra


not_base:
addi    $a0, $a0, -1
jal fib
addi    $a1, $v0, 0 #a1 = fib(n-1)
addi    $a0, $a0, -2
jal fib

b_k:
lw  $ra, 0($sp)
lw  $a0, 4($sp)
lw  $a1, 8($sp)
add $v0, $v0, $a1           #fibn = fib n-1 + fib n-2
addi    $sp, $sp, 12
jr  $ra

print_end:
addi    $a0,$v0, 0
jal Print_integer


bottom:

la  $a0, done   # mark the end of the program
jal Print_string

jal Exit0   # end the program, default return status


.data
# global data is defined here




.text

.globl  Print_integer
Print_integer:  # print the integer in register $a0 (decimal)
li  $v0, 1
syscall
jr  $ra

There's no need to save and restore $a0 in the middle of the function. You're saving/restoring $a0 upon entry/exit, so when fib(n-1) returns $a0 will be n-1 , so to get n-2 you just subtract 1 again:

# In:  $a0 = n
# Out: $v0 = fib(n)
fib:
    addiu $sp,$sp,-8
    sw $a0,0($sp)
    sw $ra,4($sp)

    sltiu $t0,$a0,2
    beq $t0,$zero,recurse

    # Base case: return n
    move $v0, $a0
    j return

recurse:
    # Compute fib(n-1)
    addiu $a0,$a0,-1
    jal fib

    # Save fib(n-1) on the stack    
    addiu $sp,$sp,-4
    sw $v0,($sp)

    # Compute fib(n-2)
    addiu $a0,$a0,-1
    jal fib

    # Return fib(n-1) + fib(n-2)
    lw $t0,($sp)
    addiu $sp,$sp,4
    addu $v0,$v0,$t0

return:
    lw $ra,4($sp)
    lw $a0,0($sp)
    addiu $sp,$sp,8
    jr $ra

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM