2013-09-24 66 views
1

我一直在負責編寫功能1內執行下列數學運算遞歸MIPS彙編程序:如何在MIPS彙編中執行遞歸操作?

(-3)*function1(n-2) + 7*function1(n-3) + 15 

該方案是在C建模:

// The function1 is a recursive procedure defined by: 
// function1(n) = 1 if n <= 2 
// = (-3)*function1(n-2) + 7*function1(n-3) + 15 otherwise. 
int function1(int n) 
{ 
if (n <= 2) 
{ 
return 1; 
} 
else 
{ 
int comp = (-3)*function1(n-2) + 7*function1(n-3) + 15; 
return comp; 
} 
} 
// The main calls function1 by entering an integer given by a user. 
void main() 
1 of 2{ 
int ans, n; 
printf("Enter an integer:\n"); 
// read an integer from user and store it in "n" 
scanf("%d", &n); 
ans = function1(n); 
// print out the solution computed by function 1 
printf("The solution is: %d\n", ans); 
return; 
} 

我寫的代碼,它編譯和執行得很好,但給我不正確的值:

.data 
mes1: .asciiz "\nEnter an integer: " 
mes2: .asciiz "The solutinon is: " 

.text 
    .globl main 

main: 
    #Display message 
    la $a0, mes1 
    li $v0, 4 
    syscall 
    #Retrieve Value 
    li $v0, 5 
    syscall 
    #Store value into $a0 and jump to function1 
    move $a0, $v0 
    jal function1 

    #Store return value to $t0 
    move $t0, $v0 

    #Display solution 
    la $a0, mes2 
    li $v0, 4 
    syscall 
    move $a0, $t0 
    li $v0, 1 
    syscall 

    #End 
    li $v0, 10 
    syscall 



function1: 
    #Store return address 
    addi $sp, $sp, -4 
    sw $ra, 0($sp) 

    #Store $a0 to stack 
    addi $sp, $sp, -4 
    sw $a0, 0($sp) 

    #If($a0<3):$t0=1:$t0=0 
    slti $t0, $a0, 3 

    #if($t0=0):math 
    beq $t0, $zero, math 
    addi $v0, $zero, 1 

    #Retrieve from stack 
    lw $a0, 0($sp) 
    addi $sp, $sp, 4 
    lw $ra, 0($sp) 
    addi $sp, $sp, 4 

    jr $ra 

math: 
    addi $a0, $a0, -2 
    jal function1 
    mul $s0 $v0, -3 
    addi $a0, $a0, -3 
    jal function1 
    mul $s1, $v0, 7 
    add $s1, $s0, $s1 
    addi $v0, $s1, 15 

    #Retrieve from stack 
    lw $a0, 0($sp) 
    addi $sp, $sp, 4 
    lw $ra, 0($sp) 
    addi $sp, $sp, 4 

    jr $ra 

當我輸入6,它應該輸出91.目前,我t的輸出44.也許更令人不安,每當我輸入任何值時,輸出數字總是可以被4整除。對於我的生活,我無法弄清楚什麼是錯誤的。任何人都可以建議嗎?

CNC中

我考慮到了@關於保護$ A0托馬斯巴丹評論。我嘗試過:

math: 
    #Store $a0 to stack 
    addi $sp, $sp, -4 
    sw $a0, 0($sp) 

    addi $a0, $a0, -2 
    jal function1 
    mul $s0, $v0, -3 

    #Retrieve from stack 
    lw $a0, 0($sp) 
    addi $sp, $sp, 4 

    addi $a0, $a0, -3 
    jal function1 
    mul $s1, $v0, 7 
    add $s1, $s0, $s1 
    addi $v0, $s1, 15 

    #Retrieve from stack 
    lw $a0, 0($sp) 
    addi $sp, $sp, 4 
    lw $ra, 0($sp) 
    addi $sp, $sp, 4 

    jr $ra 

但它仍然返回不正確的值,儘管接近正確的數字。

回答

3

好吧,我會任命一些錯誤,這不是一個完整的調試會話:

function1: 
... 
#If($a0<3):$t0=1:$t0=0 
slti $t0, $a0, 3 

#if($t0=0):sub1 
beq $t0, $zero, math 

#Load 4 to $v0 
addi $v0, $zero, 4 // I thought you should return 1 
... 

math: 
addi $a0, $a0, -2 // you are changing $a0 here 
jal function1 
lw $t2, constn3 
mult $v0, $t2 
mflo $t0   // you use $t0 to keep temporary values, but you function change $t0 too (look above, at instruction slti). You need to protect its contents 
addi $a0, $a0, -3 // but you need your original value here 
jal function1 
lw $t2, const7 
mult $v0, $t2 

EDITED

正如我在評論說,你需要保留所有的寄存器,需要保持程序調用之間的狀態。

如果您遵循MIPS約定的調用,它說您必須保存您在函數內使用的s *系列的任何寄存器。您使用其中兩個s0和s1,因此,您必須將它們保存在入口點。嗯,這是另一個問題,你必須只有一個入口點和一個出口點。

function1: 
#Store return address 
addi $sp, $sp, -12 
sw $ra, 0($sp) 
sw $s0, 4($sp) 
sw $s1, 8($sp) 

#If($a0<3):$t0=1:$t0=0 
slti $t0, $a0, 3 

#if($t0=0):math 
beq $t0, $zero, math 
addi $v0, $zero, 1 
j exit 

math: 
addi $sp, $sp, -4 
sw $a0, 0($sp) 
addi $a0, $a0, -2 
jal function1 
lw $a0, 0($sp) 
addi $sp, $sp, 4 

addi $t6, $zero, -3 
mul $s0 $v0, $t6 

addi $sp, $sp, -4 
sw $a0, 0($sp) 
addi $a0, $a0, -3 
jal function1 
lw $a0, 0($sp) 
addi $sp, $sp, 4 

addi $t6, $zero, 7 
mul $s1, $v0, $t6 
add $s1, $s0, $s1 
addi $v0, $s1, 15 

#Retrieve from stack 
exit: 
lw $ra, 0($sp) 
lw $s0, 4($sp) 
lw $s1, 8($sp) 
addi $sp, $sp, 12 

jr $ra 
+0

我已更新我的代碼。在addi $ v0中,$ zero,4行應該是1而不是4.關於你的第二條評論,我相信我應該把$ a0遞減2,直到function1返回1.關於你的第三條評論,我已經完成了mflo,並使用了mul。我也使用了不同的寄存器,所以我不覆蓋它們。關於評論4,我再一次認爲這是由堆棧處理的,必要的與評論2相似? – rphello101

+0

輸入6現在輸入-35 – rphello101

+1

例如,如果n = 5,則必須調用您的函數爲:'(-3)* function1(3)+ 7 * function1(2)+ 15'。在你的代碼中,你用$ a0 = 3調用第一個函數1,但在第二次調用中,你的$ a0 = 3 - 3,即0 – Amadeus