分岐命令とジャンプ命令
分岐命令
b (無条件分岐)
無条件にラベル Label に分岐する。
ここで分岐先のアドレスは16bitの相対アドレス
b Label
bnez (条件分岐)
の時にLabelに分岐する。
bnez $s0, Label
beqz (条件分岐)
の時にLabelに分岐する。
beqz $s0, Label
ジャンプ命令
j
ラベルLabelにジャンプする。
分岐先のアドレスは28bitのアドレス
j Label
アドレッシングモード
絶対アドレッシング
ジャンプ先のアドレスそのものを書く。
ジャンプ
相対アドレッシング
"ここから~byte先"という形で表現する
分岐
実際に翻訳してみる
loop.c
int i;
int j;
int main()
{
i = 1;
j = 0;
loop_begin:
if (i > 100)
goto loop_end;
j = j + i;
i = i + 1;
goto loop_begin;
loop_end:
return 0;
}
これをMIPSのコードにすると
loop.asm
# データ領域開始の宣言
.data
# int p
.globl p
p: .word 0
# int q
.globl q
q: .word 0
# テキスト領域開始の宣言
.text
# int main ()
.globl main
main:
# p = 1
li $s0, 1
la $t0, p
sw $s0, 0($t0)
# q = 0
la $t0, q
sw $zero, 0($t0)
# loop_begin
loop_begin:
# if (p > 100) goto loop_end
la $t0, p
lw $s0, 0($t0)
li $s1, 100
sgt $t0, $s0, $s1
bnez $t0, loop_end
# q = q + p
la $t0, q
lw $s0, 0($t0)
la $t1, p
lw $s1, 0($t1)
add $s0, $s0, $s1
sw $s0, 0($t0)
# p = p + 1
la $t0, p
lw $s0, 0($t0)
addi $s0, $s0, 1
sw $s0, 0($t0)
# goto loop_begin
b loop_begin
# loop_end
loop_end:
# return 0
li $v0, 0
jr $ra
このままだとちゃんとp, qの値がちゃんとなっているか分からないので
loop.c
の最初に
#include <stdio.h>
最後のところに
printf("p : %d, q : %d \n", p, q);
をつけると
loop.cの実行結果
p : 101, q : 5050
また、loop.asm
の loop_end: の最後に
la $t0, p
lw $s0, 0($t0)
la $t1, q
lw $s1, 0($t1)
実行後のメモリ(decimal)を見ると
・
・
R16 [s0] = 101
R17 [s1] = 5050
・
・
となり、きちんと動いているのが分かる。
コメント