1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

MIPSアセンブリ言語入門1

Last updated at Posted at 2021-05-07

#概要

MIPSについてまとめてみた
MIPSのプログラムの実行はシミュレータのSPIMを使用している

#Hello World

##Hello Worldの表示

最初にHello Worldを表示するプログラムを作ってみる。

hello.asm
#Hello Worldを表示するプログラム

#データ
        .data
msg:    .asciiz "Hello World\n"

#テキスト

        .text
        .globl main
main:
  li    $v0, 4
        la        $a0, msg
        syscall
        jr        $ra

# end
実行結果
Hello World

##hello.asmの説明

#の後はコメントアウト
プログラムはデータ領域とテキスト領域で構成される。

###データ領域

データ領域とは変数値や計算の途中で一時的に使われる領域のこと。

hello.asmのデータ領域
        .data
msg:    .asciiz "Hello World\n"

1行目の.dataはデータ領域の開始の宣言を表す。
2行目のmsg: .asciiz "Hello World\n"はラベルmsgの宣言をしている。

ラベルを宣言することによって、このアドレスをmsgという記号で参照することができる。

###テキスト領域

テキスト領域とはプログラムを配置する領域である。

hello.asmのテキスト領域
        .text
        .globl main
main:
  li    $v0, 4
        la        $a0, msg
        syscall
        jr        $ra

# end

1行目の.textでテキスト領域の開始の宣言をする。
2行目の.globl mainで下で定義されているmainというラベルがグローバル(このプログラムの外部から見える)であることを宣言する。
3行目でラベルmainを宣言。
4行目li $v0, 4は$v0レジスタに値4をロードする。
5行目la $a0, msg$a0はレジスタに付加パラメータ(この場合は表示する文字列を格納した領域のアドレス)をロードする。
6行目syscallはシステムコールを実行する。実行するシステムコールの種類は$v0で指す
7行目jr $raは呼び出しもとに戻る(return)。アドレスは$raに格納されている。

#レジスタ

MIPSのレジスタは32個ある。

$s0〜$7 (16〜23)

プログラムの変数の値を保持

$t0〜$t7 (8〜15)

計算途中の一時的な値を保持

$zero (0)

常に0という値を持つ特別なレジスタ

#アセンブリ命令

##算術演算

###add

add $s1, $s2, $s3
$s1 = $s2 + $s3

###sub

sub $s1, $s2, $s3    
$s1 = $s2 - $s3

###addi

addi $s1, $s2, num
$s1 = $s2 + num

##データ転送

load命令とstore命令がある。

  • load命令 : 主記憶かrレジスタに値を転送する
  • store命令 : レジスタから主記憶に値を転送する

###lw

lw $s1, num($s2)
$s1 = メモリ[$s2 + num]

###sw

sw $s1, num($s2)
$s1 = メモリ[$s2 + num]

##論理演算

###and

and $s1, $s2, $s3
$s1 = $s2 \quad \& \quad $s3

###or

nor $s1, $s2, $s3
$s1 = $s2 \quad || \quad $s3

###nor

nor $s1, $s2, $s3
$s1 = ! ($s2 \quad || \quad $s3)

###sll

sll $s1, $s2, 10
$s1 = $s2 \quad << \quad 10

###sli

sli $s1, $s2, 10
$s1 = $s2 \quad >> \quad 10

##無条件ジャンプ

###j

j 2500     意味 : go to 2500

#MIPSのフィールド

op rs rt rd shamt funct
6bit 5bit 5bit 5bit 5bit 6bit
  • OP : 命令の基本操作。オペコード
  • rs : 第1のソース・オペランドのレジスタ
  • rt : 第2のソース・オペランドのレジスタ
  • rd : ディスティネーション・オペランドのレジスタ。結果を収める先
  • shamt : シフト量
  • funct : 機能コード。命令操作フィールドのバリエーションを表す。

#実際のプログラム例

##assing.asm

assign.c
int src = 1234;
int dst;

int main()
{
	dst = src;

	return 0;
}

これをMIPSのコードにコンパイルすると

assign.asm
# データ領域の宣言
        .data

# int src = 1234
        .globl    src
src:    .word     1234

# int dst
        .globl    dst
dst:    .word     0

#データ領域の宣言の終了
        .text

# int main ()
        .globl    main
main:

# dst = src;
        la    $t0, src     # srcのアドレス値をt0にロードする
        lw    $s0, 0($t0)  # t0の内容をs0にロードする
        la    $t1, dst     # dstのアドレス値をt1にロードする
        sw    $s0, 0($t1)  # s0の内容をt1にストアする

#return 0
        li    $v0, 0    # $v0に値9をロードする
        jr    $ra       # 呼び出しもとに戻る

##addition.asm

addition.c
int x1 = 1234;
int x2 = 5678;
int y;

int main()
{
	y = x1 + x2;

	return 0;
}

これをMIPSのコードにコンパイルすると

addition.asm
# データ領域開始の宣言
        .data

# int x1 = 1234
        .globl    x1
x1:     .word     1234

# int x2 = 5678
        .globl    x2
x2:     .word     5678

# int y
        .globl    y
y:      .word     0

#テキスト領域の開始
        .text

# int main
        .globl    main
main:

# y = x1 + x2
    la    $t0, x1    
    lw    $s0, 0($t0)
    la    $t0, x2
    lw    $s1, 0($t0)
    add   $s0, $s0, $s1
    la    $t0, y
    sw    $s0, 0($t0)

# return 0
    li    $v0, 0
    jr    $ra

##addition2.asm

addition2.caddition.cとほぼ変わらないが、初期値宣言をしていない。

addition2.c
int p;
int q;
int r;

int main()
{
    p = 1;
    q = 2;
    r = p + q;

    return 0;
}

これをコンパイルすると

addition2.asm
# データ領域の開始の宣言
        .data

# int p
        .globl    p
p:      .word     0

# int q
        .globl    q
q:      .word     0

# int r
        .globl    r
r:      .word     0

# テキスト領域の開始の宣言
        .text

# int main
        .globl    main
main:

# p = 1
    la    $t0, p
    li    $s0, 1
    sw    $s0, 0($t0)

# q = 2
    la    $t0, q
    li    $s0, 2
    sw    $s0, 0($t0)

# r = p + q
    la    $t0, p
    lw    $s0, 0($t0)
    la    $t0, q
    lw    $s1, 0($t0)
    add   $s0, $s0, $s1
    la    $t0, r
    sw    $s0, 0($t0)

# return 0
    li    $v0, 0
    jr    $ra

addition2.asmaddition.asmを比較してみると初期値宣言をしているaddition.asmの方が効率が良いことが分かる。

#関連記事

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?