【问题标题】:Recursive Fibonacci function in mips assemblymips 汇编中的递归斐波那契函数
【发布时间】:2020-08-11 18:45:21
【问题描述】:

我是 mips 的新手 这是作业的一部分,所以我想与其直接给出答案,不如指出错误的地方可能最适合我理解

目标是将这段 C++ 代码转换成 mips 汇编语言

#fib(int n)
#{
#   if(n == 0)
#       return 0
#   else if ( n == 1)
#       return 1
#   else
#       return fib(n-1) +fib(n-2)
#n will be stored in a0 since it is the argument
#there will be two results, fib(n-1) and fib(n-2), store in the s0 and s1, so in the stack
#return the final value in $v0





addi $s2, $zero, 10
move $a0, $s2       #move the value of n to a0 to pass the argument
jal fib
beq $zero, $zero, END


fib: #fib code

addi $sp, $sp, -12  #reserve stack space for three variable needed to store in the stack
sw $ra, 0($sp)  #for return address store in stack
sw $s0, 4($sp)  #for results store in stack
sw $a0, 8($sp)  #for first result of fib(n-1) store in the stack

beq $a0, $zero, if0
beq $a0, 1, if1

#else if case
addi $a0, $a0, -1
jal fib
move $s0, $v0

lw $a0, 8($sp)
addi $a0, $a0, -2
jal fib
add $v0, $v0, $s0

lw $s0, 8($sp)
lw $ra, 0($sp)
addiu $sp, $sp, 12
jr $ra


if0:
lw $s0, 4($sp)
lw $ra, 0($sp)
addiu $sp, $sp, 12
li $v0, 0
jr $ra


if1:
lw $s0, 4($sp)
lw $ra, 0($sp)
addiu $sp, $sp, 12
li $v0, 1
jr $ra




END:
    nop

但是,当 n = 10 时,结果并没有给我 55 存储在 v0 中的当前结果给了我 21 的值 有人可以帮我弄清楚我在哪里做错了吗? 提前致谢。

【问题讨论】:

  • 你试过调试它吗?使用 MARS 或 QtSpim。
  • 附注:您可以将if (n==0) {return 0}; else if (n==1) {return 1}; 替换为if (n<=1) {return n} 以方便自己。
  • 是的,我用 mars 试过了,它没有给我任何错误。

标签: c++ mips


【解决方案1】:

您在第一次退货时有错字:

lw $s0, 8($sp)

应该是

lw $s0, 4($sp)

【讨论】:

  • 我也改了,但这里似乎没有修复程序。
  • 它对我有用。当程序跑出底部时,$v0中有0x37 = 55。
  • 啊,我是个白痴;我没有看到主标签和 .text 不在代码中 -_-
  • 为什么要将 s0 的堆栈指针从 8 更改为 4?有什么区别吗?
  • 这个想法是保留调用者的$s0 值。这是通过将它保存在序言中并在尾声中恢复它来完成的——从同一个堆栈位置。如果您将其保存到 4($sp) 并从 8($sp) 恢复它,这将无法实现保存目标 - 这只是一个错误。
【解决方案2】:

这是我之前使用过的代码,它对我有用。 您可以将此代码作为基础并将您的代码与此代码进行比较

.text
.align 2
.globl main

# Computes Fibonacci Sequence
# i =  0  1  2  3  4  5  6  7  8  9  10 ...
# x =  0  1  1  2  3  5  8 13 21 34  55 ...


main:
 la $a0, prompt
 li $v0, 4
 syscall    #Prompt for Int

 li $v0, 5
 syscall    #Response

 move $a0, $v0  #Move i to the $a0 register

 jal vfib

 add  $a0, $v0, $zero  #display Result
 li $v0, 1
 syscall

 li $v0, 10   #Exit Program
 syscall


vfib: 
 #Test Values
 addi $t0, $zero, 1  #Set $t0 to 1
 beq $a0, $zero, fib0 #Go to return 0 if i = 0
 beq $a0, $t0, fib1  #Go to return 1 if i = 1
 jr fib

fib0:
 li $v0, 0   #Return 0
 jr $ra

fib1:
 li $v0, 1   #Return 1
 jr $ra

fib:
 #Free Stack Space
 addi $sp, $sp, -16  #Make room for 4 elements in stack
     #$ra and i stored now, sums later
 sw $ra, 0($sp)  #Save return address
 sw $a0, 4($sp)  #Save i

 #Calculate (fib(n-1))
 addi $a0, $a0, -1  #Decrement i
 jal vfib   #recurse for (fib(n-1))
 sw $v0, 8($sp)  #Save value of (fib(n-1))

 #Calculate (fib(n-2))
 lw $a0, 4($sp)  #restore value of i from stack
 addi $a0, $a0, -2  #Decrement i twice
 jal vfib   #recurse for (fib(n-2))
 sw $v0, 12($sp)  #save result of (fib(n-2))

 #Restore from stack and sum
 lw $ra, 0($sp)  #Load return address
 lw $t0, 8($sp)  #load (fib(n-1))
 lw $t1, 12($sp)  #load (fib(n-2))
 addi $sp, $sp, 16  #free up 4 elements on stack
 add $v0, $t0, $t1  #Sum (fib(n-1) + fib(n-2))

 jr $ra

.data
prompt:  .ascii "Enter a non-negative integer: "

【讨论】:

  • jr fib?也许你的意思只是j fib
猜你喜欢
  • 1970-01-01
  • 2021-02-13
  • 2011-08-02
  • 2012-11-06
  • 2013-10-13
  • 2021-07-18
  • 2014-06-24
  • 1970-01-01
  • 2015-12-21
相关资源
最近更新 更多