2011-03-27 5 views
0

피보나치 시퀀스 번호를 만들고 사용자가 입력 한 숫자가 유효한 Fib인지 확인해야합니다. 번호. 그것은 입력 된 숫자까지 n 개의 숫자를 표시해야하는 경우입니다. N은 사용자가 지정합니다. 예를 들어, Fib로 3을 선택하면. 숫자와 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

일반적으로 어셈블러는 지연 슬롯을 처리합니다. '.set noreorder' 지시어를 사용하지 않는다면 최소한 GNU 어셈블러를 수행합니다. –

+0

@Laurent, 심각하게? 글쎄, 그때 좋았어. 필자는 가장 낮은 레벨 (동적으로 바이너리 코드를 방출 함)에서 MIPS와 함께 작업 했으므로 지연 슬롯이 많은 혼란이있었습니다. 그렇기 때문에 어셈블러가 이러한 문제를 해결하는 방법을 알지 못합니다. – xappymah

+1

AFAIK, GNU 어셈블러는 지연 슬롯이있는 명령어를 이전 프레임과 스왑하고, 종속성을 손상시키지 않도록 시도합니다. 대부분의 경우 실패하고 단순히 NOP를 삽입합니다. 주어진 프로젝트 내에서 어셈블리에 쓰여질 가치가있는 라인에 대해 솔직히 말하면, 저는 개인적으로 지연 슬롯을 직접 처리하는 것을 선호합니다 (그러므로'.set noreorder' 지시어). 그리고 프로젝트가 대부분 어셈블리에있을 때, 당신은 확실히 자신이 처리하는 데 필요한 기술을 가지고 있습니다. 다시 말하지만, 어셈블러가 그 일을 할 가치는 없습니다. –

0

, 거기에 이상한 일이 많이, 예를 들면 다음과 같습니다

  • 증가 할 지시가없는 또는 RecursiveFunction를 입력 할 때
  • 레지스터가 저장된 스택 포인터를 감소

제 조언은 대부분의 코드를 C로 작성하고 재귀 함수에 대해서만 MIPS로 재생하기 시작하는 것입니다. 당신이 그것을 얻었 으면 나머지를 쓰면서 일을 끝내십시오.