あなたは素晴らしい仕事をしました。最初にCコードを作成する。あなたはとても近くにいた。
計算ステップと関数エピログコードを追加する必要がありました。
また、メインプリント後に番号がで、のシステムコール10(終了)があったため、コードが無限に流れて無限に再帰するバグがありました。
CIPSを少し修正したので、MIPSコードと互換性があります。
楽しいと簡単なテストのために、私はループをメインに変更し、負の数になるまで再起動しました。
私は[無償スタイルのクリーンアップをご容赦ください]クリーンアップとコードをテストし、注釈を追加しました:他人への礼儀として
.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
を、あなたはあなたの質問が壊れフォーマットで出てくる見た場合にそれを修正してくださいあなた自身。次回はプレビューを使用してください。コードに関しては、再帰が正しいことがわかりました。残っているのは、式を評価して関数から戻ることだけです。 – Jester
Andrew、関数が "再帰的"であるとき、それが何を意味するかあなた自身の言葉で教えてください。 –
n <= 0の場合、関数はスタック領域を使い果たすまで繰り返します。 if(n <= 2)が2を返してCの例を開始した方が良いかもしれません。 – rcgldr