用户应在(3-30)之间输入一个数字,程序应输出他们要求的许多斐波纳契计算。我的程序正在打印所有30个斐波那契数字。我知道我把它设置为30,但那是看我的计算是否正确。我正在使用MIPS汇编语言。
.data
my_string: .asciiz "How many Fibonacci numbers you would like to calculate (3-30): "
fibs: .word 3 : 30
size: .word 30
space:.asciiz " "
head: .asciiz "The Fibonacci numbers are:\n"
.text
.globl main
main:
li $v0, 4
la $a0, my_string
syscall
li $v0, 5
syscall
move $v0, $t7
la $t0, fibs # load array
la $t5, size
lw $t5, 0($t5)
li $t2, 1
add.d $f0, $f2, $f4
sw $t2, 0($t0)
sw $t2, 4($t0)
addi $t1, $t5, -2
loop:
lw $t3, 0($t0) # get values from array
lw $t4, 4($t0)
add $t2, $t3, $t4
sw $t2, 8($t0)
addi $t0, $t0, 4
addi $t1, $t1, -1
bgtz $t1, loop
la $a0, fibs
add $a1, $zero, $t5
jal print
li $v0, 10
syscall
#print loop numbers
print:
add $t0, $zero, $a0
add $t1, $zero, $a1
la $a0, head
li $v0, 4
syscall
out:
lw $a0, 0($t0)
li $v0, 1
syscall
la $a0, space
li $v0, 4
syscall
addi $t0, $t0, 4
addi $t1, $t1, -1
bgtz $t1, out
jr$31
答案 0 :(得分:1)
每当您发现自己对某个程序感到困惑时,您就可以使用此策略:
浏览程序,了解它的作用
只需寻找功能块,例如:" 某处应该有一个循环...... "或" 它在哪里跳跃?"。
您不必清楚地了解该计划,只需将其划分为主要部分即可
有时你必须猜测。
从第一部分开始,对每个部分进行评论和反向工程 您可能需要评论单个指令或小指令组 要特别注意寄存器的使用方式,每个寄存器的值。
使用调试器逐步执行程序 这将帮助您在最困难的情况下以及使用冗长或棘手的程序时。
在我们的案例中,程序非常简单,我们可以在第2步停止:
.data
#Strings
my_string:
.asciiz "How many Fibonacci numbers you would like to calculate (3-30): "
space:
.asciiz " "
head:
.asciiz "The Fibonacci numbers are:\n"
#Array of fibonacci numbers
fibs: .word 3 : 30
#Size
size: .word 30
.text
.globl main
main:
#Print string
li $v0, 4
la $a0, my_string
syscall
#Read integer into v0
li $v0, 5
syscall
#Overwrite v0 with t7
#Faulty code!
move $v0, $t7
#Load address of fibonacci array into t0
la $t0, fibs # load array
#t0 = Current address into Fibonacci array
#Load size into t5 (MIPS is RISC, no load-from-immediate-address instruction ava)
la $t5, size #Load address of size into t5
lw $t5, 0($t5) #Load word from t5
#t5 = Number of numbers to compute
#Load first (and second, they are equal) Fibonacci number into t2
li $t2, 1
#Totally unrelated FB instruction?
#Remove this!
add.d $f0, $f2, $f4
#Store the first and second Fibonacci number into...
sw $t2, 0($t0) #... the first
sw $t2, 4($t0) #... and second array position (each position is 4 byte)
#Set t1 = t5 - 2 = size = 2
#t1 is the number of numbers left to compute, we skip the first two we already computed (thus the -2)
addi $t1, $t5, -2
#t1 = Number of numbers left to do
loop:
#t0 points to the second from last number in the array
#Get the second from last number from the array
lw $t3, 0($t0) # get values from array
#Get the last number from the array
lw $t4, 4($t0)
#Compute the next Fib number into t2
add $t2, $t3, $t4
#Store it into the array (at fibs[t0+2])
sw $t2, 8($t0)
#Advance t0 to point to the next number
addi $t0, $t0, 4
#Decrement the counter (number left to compute)
addi $t1, $t1, -1
#Jump if t1>0 back to the start of the loop
bgtz $t1, loop
#Call print with the array address and number of items
la $a0, fibs
add $a1, $zero, $t5
jal print
#Exit
li $v0, 10
syscall
#print loop numbers
print:
#Mov arguments to t0 and t1
add $t0, $zero, $a0
add $t1, $zero, $a1
#Print string
la $a0, head
li $v0, 4
syscall
out:
#Load number from array and print it
lw $a0, 0($t0)
li $v0, 1
syscall
#Print space
la $a0, space
li $v0, 4
syscall
#Move t0 to the next number (each number occupies 4 bytes)
addi $t0, $t0, 4
#Decrement the number left to do
addi $t1, $t1, -1
#If t1 > 0 jump back to the start of the loop (out)
bgtz $t1, out
#Return
jr $31
不考虑此处和那里的非相关指令,循环开始时的寄存器使用是:
t0 =上次计算的数字的第二个地址
t0 + 4 =最后一个计算机编号的地址
t1 =要做的数字
t5 =要计算的总数
另外t1 = t5 - 2
。
所以应该很容易使这个程序适用于用户的大小。
只需更改move $v0, $t7
(这是错误的,因为将t7移动到v0,覆盖存储用户号码的唯一地方!)
#Store v0 into size
la $t5, size
sw $v0, 0($t5)
你应该注意到这个程序在输入少于1时不会工作。
您可以将其修复为练习。