MIPSアセンブリ言語入門4

#配列

MIPSでは**1word**が**4byte**なので、i番目の要素のアドレスは$ 0番目の要素のアドレス+4i$となる。

`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`を使う

#システムコール

システムコールはMIPSでは`syscall`を使って実現する
実行したいシステムコールの番号を`$v0`に入れる

###syscallパラメータ

* print_int : 1
* print_string: 4
* read_int : 5

1. $v0レジスタにsyscallのパラメータをセット
2. $a0レジスタに引数をセット
3. 結果が$v0に格納される

#実際にしてみる


##配列

```C: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;
}
```

これをMIPSのコードで書くと

```: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
```


##ポインタ

```C: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
```

##システムコール

```C: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
    li    $v0, 0
    jr    $ra
```

実行結果は

```:実行結果
x = 3
y = 7
x + y = 10
```
となる。

#関連記事

https://qiita.com/twrcd1227/items/91f048de69bf92355868

https://qiita.com/twrcd1227/items/405cf58e8c9fcd3447ac

https://qiita.com/twrcd1227/items/f0dfcd9bd8f81989cfe9