配列
MIPSでは1wordが4byteなので、i番目の要素のアドレスはとなる。
int a[4] = {10, 20, 30, 40}
の配列の宣言は
.globl a # 配列の先頭アドレス
a: .word 10 # a[0]
.word 20 # a[1]
.word 30 # a[2]
.word 40 # a[3]
となる。
a[i]のアドレス計算方法は以下のようにする。
la $t0, i #iのアドレス
lw $t1, 0($t0)
li $t2, 4
mul $t1, $t1, $t2
la $t2, a
addu $t0, $t1, $t2
ポインタ
MIPSにポインタ用の命令語はない
int *p;
は以下のようになる
.globl p
p: .word 0
アドレス演算子&
はla
を使う
システムコール
システムコールはMispではsyscall
を使って実現する
実行したいシステムコールの番号を$v0
に入れる
syscallパラメータ
- print_int : 1
- print_string: 4
- read_int : 5
- $v0レジスタにsyscallのパラメータをセット
- $a0レジスタに引数をセット
- 結果が$v0に格納される
実際にしてみる
配列
array.c
int sum;
int i;
int a[] = {9, 5, 1, 7, 10, 12, 2};
int main () {
i = 0;
sum = 0;
while (i < 7) {
sum = sum + a[i];
i = i + 1;
}
return 0;
}
これをMISPのコードで書くと
array.asm
# データ領域開始の宣言
.data
# int sum
.globl sum
sum: .word 0
# int i;
.globl i
i: .word 0
# int a[] = {9, 5, 1, 7, 10, 12, 2};
.globl a
a: .word 9
.word 5
.word 1
.word 7
.word 10
.word 12
.word 2
# テキスト領域開始の宣言
.text
# int main () {
.globl main
main:
# i = 0;
la $t0, i
sw $zero, 0($t0)
# sum = 0
la $t0, sum
sw $zero, 0($t0)
# while (i < 7) {
l_bwh:
la $t0, i
lw $s0, 0($t0)
li $s1, 7
slt $t0, $s0, $s1
beqz $t0, l_ewh
# sum = sum + a[i];
la $t0, sum
lw $s0, 0($t0)
la $t0, i
lw $s1, 0($t0)
li $t1, 4
mul $s1, $s1, $t1
la $t0, a
add $t0, $t0, $s1
lw $s2, 0($t0)
add $s0, $s0, $s2
la $t0, sum
sw $s0, 0($t0)
# i = i + 1;
la $t0, i
lw $s0, 0($t0)
addi $s0, $s0, 1
sw $s0, 0($t0)
b l_bwh
# } return 0;
l_ewh:
li $v0, 0
jr $ra
ポインタ
pointer.c
int x = 0;
int y = 2017;
int *p;
int main () {
p = &x;
*p = *p + 1;
p = &y;
*p = *p - 1;
return 0;
}
pointer.asm
# データ領域開始の宣言
.data
# int x = 0
.globl x
x: .word 0
# int y = 0
.globl y
y: .word 2017
# int *p
.globl p
p: .word 0
# テキスト領域開始の宣言
.text
# int main ()
.globl main
main:
# p = &x
la $t0, p
la $t1, x
sw $t1, 0($t0)
# *p = *p + 1
la $t0, p
lw $t1, 0($t0)
lw $t2, 0($t1)
addi $t2, $t2, 1
sw $t2, 0($t1)
# p = &y
la $t0, p
la $t1, y
sw $t1, 0($t0)
# *p = *p - 1
li $s0, 1
la $t0, p
lw $t1, 0($t0)
lw $t2, 0($t1)
sub $t2, $t2, $s0
sw $t2, 0($t1)
li $v0, 0
jr $ra
システムコール
print.c
#include <stdio.h>
int x;
int y;
int main () {
printf("x = ");
scanf("%d", &x);
printf("y = ");
scanf("%d", &y);
printf("x + y = ");
printf("%d", x + y);
printf("\n");
return 0;
}
これをMipsで書くと
print.asm
.data
# int x, y
.globl x
x: .word 0
.globl y
y: .word 0
# 表示する文字の定義
_s1: .asciiz "x = "
_s2: .asciiz "y = "
_s3: .asciiz "x + y = "
_s4: .asciiz "\n"
.text
# int main()
.globl main
main:
# printf("x = ")
li $v0, 4
la $a0, _s1
syscall
# x = read_int();
li $v0, 5
syscall
la $t0, x
sw $v0, 0($t0)
# printf("y = ")
li $v0, 4
la $a0, _s2
syscall
# y = read_int();
li $v0, 5
syscall
la $t0, y
sw $v0, 0($t0)
# printf("x + y = ")
li $v0, 4
la $a0, _s3
syscall
# printf("%d", x + y)
la $t0, x
lw $s0, 0($t0)
la $t0, y
lw $s1, 0($t0)
add $a0, $s0, $s1
li $v0, 1
syscall
# printf("\n = ")
li $v0, 4
la $a0, _s4
syscall
#return 0
jr $ra
実行結果は
実行結果
x = 3
y = 7
x + y = 10
となる。
コメント