0
@twrcd1227

MIPSアセンブリ言語入門4

配列

MIPSでは1word4byteなので、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を使う

システムコール

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

syscallパラメータ

  • print_int : 1
  • print_string: 4
  • read_int : 5
  1. $v0レジスタにsyscallのパラメータをセット
  2. $a0レジスタに引数をセット
  3. 結果が$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

となる。

関連記事

0
ユーザー登録して、Qiitaをもっと便利に使ってみませんか。
  1. あなたにマッチした記事をお届けします
    ユーザーやタグをフォローすることで、あなたが興味を持つ技術分野の情報をまとめてキャッチアップできます
  2. 便利な情報をあとで効率的に読み返せます
    気に入った記事を「ストック」することで、あとからすぐに検索できます
twrcd1227
海外旅行とカメラが趣味です。
この記事は以下の記事からリンクされています
twrcd1227MIPSアセンブリ言語入門3からリンク

コメント

この記事にコメントはありません。
あなたもコメントしてみませんか :)
ユーザー登録
すでにアカウントを持っている方はログイン
記事投稿イベント開催中
Azure AIを活用した機械学習に関する記事を投稿しよう!
~
フロントエンド強化月間 - 開発する上で知っておくべき知見を共有しよう
~