我工作的分配類似於二叉樹時遇到困難,瞭解如何正確C.編寫以下問題遞歸過程要將呼叫在MIPS
int choose(int n, int k){
if (k == 0) {
return 1;
} else if (n == k) {
return 1;
} else if (n < k) {
return 0;
} else {
return choose(n-1, k-1) + choose(n-1, k);
}
}
我的想法是使用三個寄存器每次調用$s0, $s1, $s2
時將值存儲到堆棧中,其中$s0
將包含更新後的值n
; $s1
將維持值k
;並且$s2
將在第二個choose(n-1, k)
中保留值k
,因爲該值只會在父呼叫改變時纔會降低。我選擇這個的原因是因爲k
的值不是從這個函數中的每個調用中減去的,它應該是相同的,直到父進程在先前的調用中遞減它爲止。
這是我試圖做的Choose
程序。問題是我沒有得到正確的答案,當然。
Choose:
#store current values onto stack
addi $sp, $sp, -16
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
sw $s2, 12($sp)
#check values meet criteria to add to $v0
beq $s1, $0, one
beq $s0, $s1, one
blt $s0, $s1, zero
beq $s2, $0, one
#no branches passed so decrement values of n and k
subi $s0, $s0, 1
subi $s1, $s1, 1
#move values of registers to $a's for argument passing
move $a0, $s0
move $a1, $s1
jal Choose #call procedure again
#this is where I'm having my problems
#not sure how to loop the procedure to get
#the second half of the equation Choose(n-1,k)
#which is the reason for the next 2 lines of code
move $a2, $s2
jal Choose
add $v0, $v0, $v1
j Choose_Exit
#add one to $v1 from branch passed
one:
addi $v1, $v1, 1
j Choose_Exit
#branch returns 0
zero:
addi $v1, $v1, 0
j Choose_Exit
#return values to caller from stack
Choose_Exit:
lw $s2, 12($sp)
lw $s1, 8($sp)
lw $s0, 4($sp)
lw $ra, 0($sp)
addi $sp, $sp, 16
jr $ra
所以我在瞭解如何正確地實現兩倍於該遞歸過程將它們加在一起的問題。我可以理解如何在MIPS中創建遞歸過程來執行階乘,因爲這總是任何語言的遞歸定義。但是,使用不同論點的遞歸,然後將它們加在一起會讓我困惑不已。
當寫在紙上時,我明白這個過程可以用父母和孩子的二叉樹來表示。父母是單功能Choose(n,k)
,孩子是Choose(n-1, k-1) + Choose(n-1, k)
,並且葉子孩子從if
聲明中分支一次,它將一個數字傳遞給等待另一個被呼叫者部分的加數的父母返回其值等。等等
任何幫助指出我在正確的方向,我做錯了什麼我的方法會很好。我明白了一開始,我明白了最後,只需要一些幫助來幫助理解中間最重要的部分。
第1步:建立一個約定 - 參數進入'$ a0'和'$ a1',返回值到'$ v0'和寄存器'$ s0' -' $ s7'是callee-save(即退出前必須恢復)。第二步:堅持慣例 - 你知道現在的論點在哪裏。如果您需要使用'$ s'寄存器,請將其保存在堆棧中,並在最後將其恢復。如果您需要在呼叫中保留一個值,請將其移入「$ s」寄存器。步驟3:程序 - 一旦你在'$ v0'中選擇了(n-1,k-1)*的結果*將它移動到一個保存的寄存器並且調用*選擇(n,k-1)*。從這裏繼續。 –
請注意,「*移入'$ s'寄存器*」符合使用條件。所以,如上所述,你還需要... –
@MargaretBloom感謝您的意見。我理解你對約定的描述以及爲什麼它很重要。我的教授已經告訴我們你說的是什麼,你是對的,因爲我應該使用這個約定。有了這個說法,我仍然不確定我如何用我現在的代碼實現我想要的。我真的很感激更多的關於如何在需要不同的參數值的時候發生單個遞歸過程的實例。當第一次調用這個過程時,我沒有包含所有使用'$ a#'寄存器的代碼來傳遞參數。 – Pwrcdr87