割り当てに問題があります。助けていただければ幸いです。私は答えを求めているのではなく、2つと2つを組み合わせて自分で理解することを好みますが、MIPSについてはほとんど知らないので、どこから始めればよいのかわかりません。
これが私が始めたものです
.data
.text
main:
addi $sp, $sp, -16 #prepare stack for 4 items
sw $s0, 0($sp)
sw $s1, 4($sp)
sw $s2, 8($sp)
sw $ra, 12($sp)
move $s0, $a0
move $s1, $a1
add $s2, $s0, $s1 #add two previous numbers and store result in $s2
move $v0, $s2 #put answer into $v0
lw $s0, 0($sp)
lw $s1, 4($sp)
lw $s2, 8($sp)
lw $ra, 12($sp)
addi $sp, $sp, 16
jr$ra
基本的に、再帰関数を使用してフィボナッチ数を計算し、ループを使用してフィボナッチ数列の最初の10個の数を出力します。
私は多くの例を調べましたが、それらはすべて私たちがまだ学んでいない指示を使用しているので、私はそれを理解することができず、私たちがそれらを使用することは期待されていないと思います。上記のコードでは、基本的に、$ raを3つの値、加算する2つの数値、および合計とともに格納するスタックを作成しています。私の問題の一部は、関数がどこで開始および終了するか、そして実行されている作業の全体が何であるかを理解することです。
また、印刷するには次のものを使用するように指示されました
li $v0, 1
move $a0, $s0
syscall
これが$ v0に格納されている値を出力していると考えるのは正しいですか?
前もって感謝します
これが関数のコードです。私はあなたが答えを探していないことを知っていますが、時々例を探して、それがどのように機能するかは、それが実際にどのように機能したかを理解した時点でより簡単になります。
.data
msg1: .asciiz "Give a number: "
.text
.globl main
main:
li $v0, 4
la $a0, msg1
syscall # print msg
li $v0, 5
syscall # read an int
add $a0, $v0, $zero # move to $a0
jal fib # call fib
add $a0, $v0, $zero
li $v0, 1
syscall
li $v0, 10
syscall
fib:
# $a0 = y
# if (y == 0) return 0;
# if (y == 1) return 1;
# return fib(y - 1) + fib(y - 2);
#save in stack
addi $sp, $sp, -12
sw $ra, 0($sp)
sw $s0, 4($sp)
sw $s1, 8($sp)
add $s0, $a0, $zero
addi $t1, $zero, 1
beq $s0, $zero, return0
beq $s0, $t1, return1
addi $a0, $s0, -1
jal fib
add $s1, $zero, $v0 # $s1 = fib(y - 1)
addi $a0, $s0, -2
jal fib # $v0 = fib(n - 2)
add $v0, $v0, $s1 # $v0 = fib(n - 2) + $s1
exitfib:
lw $ra, 0($sp) # read registers from stack
lw $s0, 4($sp)
lw $s1, 8($sp)
addi $sp, $sp, 12 # bring back stack pointer
jr $ra
return1:
li $v0,1
j exitfib
return0:
li $v0,0
j exitfib
Gusbroが言ったように、mipsで再帰を使用するには、2つのことを行う必要があります。 jal
(ジャンプしてリンク)を関数の名前に追加しますが、最初に常に戻りアドレスをスタックに格納します:$ra
したがって、将来、最初に戻りたい場合は、次のことができるようになります。 jr $ra
を使用する。返信先アドレスを保存せずにjr
経由でアクセスしようとすると、おそらくinvalid program counter error
が表示されます。私があなたを助けてくれて、MIPSプログラミングをよりよく理解できるように頑張ってください!
ここにいくつかのヒントがあります:
再帰関数を作成する必要がありますが、関数はまったく作成していません。この関数をMIPSアセンブラーで作成するには、最初に高級言語(C)で作成することをお勧めします。したがって、次のようになります。
int fib(int n)
{
if(n == 0 or n == 1)
return n;
else return fib(n-1) + fib(n-2);
}
最初の行は、再帰の基本ケース(n = 0またはn = 1)にあるかどうかを確認します。その場合、fib(n)はnを返します。それ以外の場合は、fib(n-1)とfib(n-2)の合計を返す再帰ステップが実行されます。
したがって、関数を記述し、入出力パラメーターを定義する必要があります(どのレジスターがnを保持し、fib(n)を返します)。Cコードを手動でコンパイルします。関数を開始するには、ラベルを追加するだけです。
fib:
jal
命令を使用します。jr $ra
を使用して関数から戻る前に、保存された値をスタックから復元します。n
に使用されるレジスタ)をロードし、次にjal fib
をロードします。