使用MIPS程序集的递归函数

The*_*ber 5 recursion mips fibonacci

我在任务上遇到了一些麻烦,并希望得到一些帮助.我不是要求答案,我宁愿把两个和两个放在一起自己解决,但我对MIPS知之甚少,我很难知道从哪里开始.

这是我开始的

.data


.text
main:

addi $sp, $sp, -16  #prepare stack for 4 items
sw $s0, 0($sp)
sw $s1, 4($sp)
sw $s2, 8($sp)
sw $ra, 12($sp)
move $s0, $a0
move $s1, $a1

add $s2, $s0, $s1   #add two previous numbers and store result in $s2

move $v0, $s2   #put answer into $v0

lw $s0, 0($sp)
lw $s1, 4($sp)
lw $s2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
jr$ra
Run Code Online (Sandbox Code Playgroud)

基本上我们使用递归函数来计算斐波那契数,并使用一个循环来打印斐波纳契数列的前10个数.

我查了很多例子,但他们都使用了我们还没有学到的指令,所以我无法理解它,我只能假设我们不应该使用它们.在上面的代码中,我基本上创建了一个堆栈来存储$ ra以及三个值,两个要添加的数字和总和.我的部分问题是了解函数的开始和结束位置以及正在完成的工作的总体情况.

我们也被给予打印您使用以下内容

li $v0, 1
move $a0, $s0
syscall
Run Code Online (Sandbox Code Playgroud)

我是否认为这是打印存储在$ v0中的值?

提前致谢

Kor*_*pel 9

这是您的功能的代码.我知道你不是在寻找答案,但有时候寻找一个例子以及它是如何工作的,在你明白它是如何工作的时候,你会更容易.

.data
msg1: .asciiz "Give a number: "

.text
.globl main
main:
    li $v0,  4
    la $a0,  msg1
    syscall             # print msg
    li $v0,  5
    syscall             # read an int
    add $a0, $v0, $zero # move to $a0

    jal fib             # call fib

    add $a0, $v0, $zero
    li  $v0, 1
    syscall

    li $v0, 10
    syscall

fib:
    # $a0 = y
    # if (y == 0) return 0;
    # if (y == 1) return 1;
    # return fib(y - 1) + fib(y - 2);

    #save in stack
    addi $sp, $sp, -12 
    sw   $ra, 0($sp)
    sw   $s0, 4($sp)
    sw   $s1, 8($sp)

    add $s0, $a0, $zero

    addi $t1, $zero, 1
    beq  $s0, $zero, return0
    beq  $s0, $t1,   return1

    addi $a0, $s0, -1

    jal fib

    add $s1, $zero, $v0         # $s1 = fib(y - 1)

    addi $a0, $s0, -2

    jal fib                     # $v0 = fib(n - 2)

    add $v0, $v0, $s1           # $v0 = fib(n - 2) + $s1

    exitfib:

        lw   $ra, 0($sp)        # read registers from stack
        lw   $s0, 4($sp)
        lw   $s1, 8($sp)
        addi $sp, $sp, 12       # bring back stack pointer
        jr $ra

    return1:
        li $v0,1
        j exitfib

    return0:     
        li $v0,0
        j exitfib
Run Code Online (Sandbox Code Playgroud)

就像Gusbro所说,为了在mips中使用递归,你将不得不做两件事.jal(跳转和链接)到函数的名称,但首先总是将返回地址存储到堆栈中:$ra所以将来如果要返回到开头,您将能够使用jr $ra.如果您不保存退货地址并尝试通过jr您访问它,很可能会得到一个invalid program counter error.希望我帮助你,并通过MIPS编程获得更好的掌握!