MIPS帮助:递归函数 [英] MIPS Help: Recursive Functions

查看:467
本文介绍了MIPS帮助:递归函数的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想code这个递归函数到MIPS。
我的问题是我不知道我该怎么办的递归步骤。结果
我是pretty确保我得到了休息是正确的。

  INT复发(INT N){
    如果(N == 1 ||ñ== 2){
           返回2;
    }其他{
           回报(正 - 4)+ N *复发(N-2);
    }
}

 。数据promptMessage:.asciiz输入一个数字是大于或等于0:
resultMessage:.asciiz\\ n此回答是:
输入:.word 0
回答:0 .word。文本
.globl主主要:
从用户#阅读数
李$ V0,4
LA $ A0,promptMessage
系统调用李$ V0,5
系统调用SW $ V0,输入#CALL功能
LW $ A0,输入
日航复发
SW $ V0,答案#Display结果
李$ V0,4
LA $ A0,resultMessage
系统调用李$ V0,1
LW $ A0,答案
系统调用.globl复发复发:
阿迪$ SP,SP $,-8
SW $ A0,0($ SP)
SW $ RA,4($ SP)#Base情况下,如果(N == 0 ||ñ== 1)返回2;
李$ V0,2
BEQ $ A0,$零,DONE
BEQ $ A0,1,DONE#RECURSIVE STEP
阿迪$ A0,$ A0,-2
日航复发


解决方案

您做的非常出色。首先创建C $ C $℃。你是非常接近的。

我不得不添加的计算步骤和功能收尾code。

此外,还有那里的主要打印的号码后,出现了一个错误的没有的系统调用10(退出),这样code只会落空和无限递归。

我修改了C $ C $ç稍微所以这将是与MIPS code更兼容。

只是为了好玩,并便于测试,我直到它得到一个负数改变主循环并重新提示。

我已经清理并测试了code,补充注释[请原谅无偿风格清理]:

 。数据#注意:这应首先出现,以保持对齐到4字节边界
#(或.align伪4将做到这一点),否则,LW / SW运营人员可以在一个失败
#对齐异常
    .align伪4
输入:.word 0
回答:0 .wordpromptMessage:.asciiz输入一个数字,大于或等于0(-1停止):
resultMessage:.asciiz\\ n此回答是:
NL:.asciiz\\ n    的.text .globl主要:
    # 用户提示
    李$ v0,4
    LA $ A0,promptMessage
    系统调用    #从用户阅读次数
    李$ v0,5
    系统调用
    SW $ V0,输入    #负值意味着停止
    #注:此添加
    bltz $ V0,main_exit    #调用函数
    LW $ A0,输入
    日航复发
    SW $ V0,答案    #显示结果消息
    李$ v0,4
    LA $ A0,resultMessage
    系统调用    #显示编号
    李$ v0,1
    LW $ A0,答案
    系统调用    #输出换行符
    李$ v0,4
    LA $ A0,NL
    系统调用    #注意:这是添加到允许多次尝试,但没有它,有
    #下面的bug
    J主    #BUG:系统调用来这里退出是_missing_等得了fallthrough为复发
    #导致堆栈溢出
main_exit:
    李$ v0,10
    系统调用    .globl复发#复发 - 递归

#参数:
#A0 - 在N的价值

#伪code:
#* INT
#*易复发(INT N)
#* {
#* INT R;
#*
#*如果(N == 1 ||ñ== 2){
#*回报2;
#*}
#*
#* R =复发(N - 2);
#*
#*回报(N - 4)+(N * R);
#*}
复发:
    阿迪$ SP,SP $,-8
    SW $ a0,0($ SP)
    SW $ RA,4($ SP)    #基本情况,如果(N == 0 ||ñ== 1)返回2;
    李$ v0,2
    BEQ $ A0,$零,recur_done
    BEQ $ a0,1,recur_done    #递归步骤
    阿迪$ A0,$ A0,-2#N - = 2
    日航复发
    我们需要LW $ a0,0($ SP)#N背(否(N - 2))    #注:此计算失踪
    MUL $ V0,V0 $,$ A0#R * = N(即(N * R))
    阿迪$ A0,$ A0,-4#N - = 4(即(N - 4))
    加$ V0,V0 $,$#A0他们总结    #注意:这是这个函数的栈序言标准逆转
recur_done:
    LW $ a0,0($ SP)
    LW $ RA,4($ SP)
    阿迪$ SP,SP $ 8
    JR $ RA

I'm trying to code this recursive function into MIPS. My problem is I'm not sure how I can do the recursive step.
I'm pretty sure I got the rest correct.

int recur(int n) {
    if(n == 1 || n == 2) {
           return 2;
    } else {
           return (n-4)+n*recur(n-2);
    }
}

.data

promptMessage: .asciiz "Enter a number that is greater than or equal to 0: "
resultMessage: .asciiz "\nThe answer is: "
input: .word 0
answer: .word 0

.text
.globl main

main:
#Read the number from the user
li $v0, 4           
la $a0, promptMessage       
syscall

li $v0, 5           
syscall         

sw $v0, input           

#Call the function
lw $a0, input           
jal recur           
sw $v0, answer      

#Display result
li $v0, 4
la $a0, resultMessage       
syscall

li $v0, 1           
lw $a0, answer          
syscall

.globl recur

recur:
addi $sp, $sp, -8       
sw $a0, 0($sp)          
sw $ra, 4($sp)          

#Base Case  if(n == 0 || n == 1) return 2;
li $v0, 2
beq $a0, $zero, DONE
beq $a0, 1, DONE

#RECURSIVE STEP
addi $a0, $a0, -2       
jal recur           

解决方案

You did a great job. Creating C code first. You were very close.

I had to add the calculation step and the function epilog code.

Also, there was a bug where after main prints the number, there was no syscall 10 (exit) so the code would just fall through and recurse infinitely.

I reworked the C code slightly so it would be more compatible with the MIPS code.

Just for fun, and ease of testing, I changed main to loop and reprompt until it gets a negative number.

I've cleaned up and tested the code, added annotations [please pardon the gratuitous style cleanup]:

    .data

# NOTE: these should appear first to maintain alignment to a 4 byte boundary
# (or the .align 4 will do it) otherwise, the lw/sw ops can fail on an
# alignment exception
    .align  4
input:      .word       0
answer:     .word       0

promptMessage:  .asciiz "Enter a number that is greater than or equal to 0 (-1 to stop): "
resultMessage:  .asciiz "\nThe answer is: "
nl:         .asciiz "\n"

    .text   .globl

main:
    # prompt user
    li      $v0,4
    la      $a0,promptMessage
    syscall

    # Read the number from the user
    li      $v0,5
    syscall
    sw      $v0,input

    # negative value means stop
    # NOTE: added this
    bltz    $v0,main_exit

    # Call the function
    lw      $a0,input
    jal     recur
    sw      $v0,answer

    # Display result message
    li      $v0,4
    la      $a0,resultMessage
    syscall

    # display number
    li      $v0,1
    lw      $a0,answer
    syscall

    # output newline
    li      $v0,4
    la      $a0,nl
    syscall

    # NOTE: this was added to allow multiple tries, but without it, there was
    # the bug below
    j       main

    # BUG: syscall to exit here was _missing_ so got fallthrough into "recur"
    # causing the stack to overflow
main_exit:
    li      $v0,10
    syscall

    .globl  recur

# recur -- recursion
#
# arguments:
#   a0 -- the "n" value
#
# pseudo code:
# * int
# * recur(int n)
# * {
# *     int r;
# *
# *     if (n == 1 || n == 2) {
# *         return 2;
# *     }
# *
# *     r = recur(n - 2);
# *
# *     return (n - 4) + (n * r);
# * }
recur:
    addi    $sp,$sp,-8
    sw      $a0,0($sp)
    sw      $ra,4($sp)

    # Base Case  if(n == 0 || n == 1) return 2;
    li      $v0,2
    beq     $a0,$zero,recur_done
    beq     $a0,1,recur_done

    # RECURSIVE STEP
    addi    $a0,$a0,-2          # n -= 2
    jal     recur
    lw      $a0,0($sp)          # we need "n" back (not (n - 2))

    # NOTE: this calculation was missing
    mul     $v0,$v0,$a0         # r *= n (i.e. (n * r))
    addi    $a0,$a0,-4          # n -= 4 (i.e. (n - 4))
    add     $v0,$v0,$a0         # sum them

    # NOTE: this is the standard reversal for this function's stack prolog
recur_done:
    lw      $a0,0($sp)
    lw      $ra,4($sp)
    addi    $sp,$sp,8
    jr      $ra

这篇关于MIPS帮助:递归函数的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆