피보나치 시퀀스 번호를 만들고 사용자가 입력 한 숫자가 유효한 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
일반적으로 어셈블러는 지연 슬롯을 처리합니다. '.set noreorder' 지시어를 사용하지 않는다면 최소한 GNU 어셈블러를 수행합니다. –
@Laurent, 심각하게? 글쎄, 그때 좋았어. 필자는 가장 낮은 레벨 (동적으로 바이너리 코드를 방출 함)에서 MIPS와 함께 작업 했으므로 지연 슬롯이 많은 혼란이있었습니다. 그렇기 때문에 어셈블러가 이러한 문제를 해결하는 방법을 알지 못합니다. – xappymah
AFAIK, GNU 어셈블러는 지연 슬롯이있는 명령어를 이전 프레임과 스왑하고, 종속성을 손상시키지 않도록 시도합니다. 대부분의 경우 실패하고 단순히 NOP를 삽입합니다. 주어진 프로젝트 내에서 어셈블리에 쓰여질 가치가있는 라인에 대해 솔직히 말하면, 저는 개인적으로 지연 슬롯을 직접 처리하는 것을 선호합니다 (그러므로'.set noreorder' 지시어). 그리고 프로젝트가 대부분 어셈블리에있을 때, 당신은 확실히 자신이 처리하는 데 필요한 기술을 가지고 있습니다. 다시 말하지만, 어셈블러가 그 일을 할 가치는 없습니다. –