2011-03-27 101 views
0

我必須創建斐波那契序列號,然後檢查用戶輸入的數字是否是有效的Fib。數。如果是,我必須顯示n個號碼,直到他們輸入的號碼。 N由用戶給出。例如,如果他們選擇3作爲他們的Fib。號和2作爲計數它應該顯示 13,8Mips遞歸問題

我所擁有的一切,直到顯示「13 8」完成。任何有關如何退回堆棧並顯示已創建的變量並隨後被覆蓋的指導,將不勝感激。謝謝!

##### The Data Segment ######### 
.data 
strNumber:  .asciiz "Enter a valid Fibonacci Number: " 
strCount:  .asciiz "Enter the numbers of Fibonacci numbers to be displayed: " 
strError:  .asciiz " is not a valid Fibonacci Number.\n" 
strMore:   .asciiz "There are no more Fibonacci Numbers to be displayed." 
newLine:   .asciiz "\n" 
strBadEntry:  .asciiz "is not a valid entry." 
strValid:  .asciiz "Valid Fib Number\n\n" 

#### The Text Segment ########## 

.text 
.globl main 

main: 
li $t3, 39 
li $t2, 0 
li $t4, 1 
li $t5, 1 
#Get the User's Number   #Gets the number from the user 
li $v0, 4 
la $a0, strNumber 
syscall 
li $v0, 5   #prepares to take in the user entered value 
syscall    #retrives what the user entered in the console 
move $s1, $v0 
bltz $v0, in_error  #calls the error function if less than 0. 
j DoneIf   #if those conditions aren't meant it jumps to the DoneIf 

in_error: 
li $t4, 1 
li $t5, 1 
li $v0, 1    # print int 
move $a0, $s1   # prints the user's number 
syscall 
li $v0, 4 
la $a0, strError 
syscall 
li $v0, 4 
la $a0, strNumber 
syscall 
li $v0, 5 
syscall 
move $s1, $v0 
bltz $v0, in_error  #recall the inerror function if still less than 0 


DoneIf:     
move $t0, $v0   #moves the value to a new location, for future use 
li $v0, 4 
la $a0, newLine 
syscall 

#Second Number    #Gets the second number from the user 
li $v0, 4 
la $a0, strCount 
syscall 
li $v0, 5 
syscall    #retrieves what the user entered in the console 
bltz $v0, in_error2  #calls the second error function if less than 0 
bgeu $v0, $t3, in_error2 #calls the second error function if greater than 63 
j DoneIf2   #jumps to the DoneIf2 if those conditions aren't met    

in_error2: 
li $v0, 4 
la $a0, strBadEntry 
syscall 
li $v0, 4 
la $a0, newLine 
syscall 
li $v0, 4 
la $a0, strCount 
syscall 
li $v0, 5 
syscall 
blez $v0, in_error2  #recalls the error2 function if number conditions stil aren't met 
bgeu $v0, $t3, in_error2 #recalls the error2 function if number conditions still aren't meet 

DoneIf2: 
move $t1, $v0 


jal RecursiveFunction  #Jump to Recursive Function 

Exit: 




RecursiveFunction: 
sw $ra, 0($sp) 
sw $t4, 4($sp) 
sw $t5, 8($sp) 


bge $t5, $t4, t5_Greater 
bgt $t4, $t5, t4_Greater 

Check: 
bgt $t4, $t0, check_t5 
check_t5: 
bgt $t5, $t0, in_error 
beq $t4, $t0, Valid 
beq $t5, $t0, Valid 
jal RecursiveFunction 



t5_Greater: 
add $t4, $t5, $t4 
j Check 

t4_Greater: 
add $t5, $t5, $t4 
j Check 







Valid: 
li $v0, 4 
la $a0, strValid  
syscall 
lw $ra, 20($sp) # Restore return address 
    lw $fp, 16($sp) # Restore frame pointer 
li $v0, 1 
move $a0, $t5 
syscall 

回答

1

這不是你的問題的答案,而是一些指導在哪裏尋找錯誤。

做關於「延遲槽」以及它是如何與在MIPS處理器的分支指令的一些研究。

+1

正常情況下,彙編程序爲您處理延遲時隙。至少在GNU彙編程序中,除非你不要使用'.set noreorder'指令 – 2011-03-28 20:45:55

+0

@Laurent來執行它,認真嗎?那麼,它的好呢。我已經在MIPS的最底層(動態地發佈二進制代碼本身),所以延遲插槽有很大的混亂。這就是爲什麼我不知道彙編程序如何解決這種情況。 – xappymah 2011-03-29 02:08:03

+1

AFAIK,GNU彙編程序只嘗試將具有延遲槽的指令與其前任交換,同時確保它不會中斷依賴關係。大多數情況下,它會失敗,只需插入一條NOP。說實話,對於在一個給定的項目中值得在程序集中編寫的代碼行,我個人更喜歡自己處理延遲插槽(因此'.set noreorder' directive)。當你的項目大部分是組裝時,你肯定有自己處理它們所需的技能。再一次,它不值得讓組裝者完成這項工作。 – 2011-03-29 06:03:22

0

除了一個事實,即代碼看起來不完整的,也有它很多的奇怪的事情,例如:

  • 沒有指示遞增或遞減堆棧指針進入RecursiveFunction
  • 寄存器保存是從來沒有恢復的

我的建議是寫你的大部分代碼在C中,並開始只使用MIPS玩遞歸函數。當你得到它,然後完成你的工作,寫下其餘的。