• 検索結果がありません。

例:

ドキュメント内 計算機構成論II第4回-7回 (ページ 50-70)

組込みシステムにおいてプログラムの速度と

メモリサイズが重要である場合。

.data

msg: .asciiz "Hello World"

.text

.globl main

main: li $v0, 4 # v0レジスタに4をセット syscall(print_str) la $a0, msg # a0レジスタにメッセージのアドレスを格納

syscall # 文字列を出力 jr $ra # リターン

Hello World のソースプログラム

疑似命令 .data データ領域の開始 疑似命令 .asciiz "Strings": 文字列を配置 ラベル

疑似命令 globl L ラベル L を大局的に参照可能な記号と宣言する

疑似命令 .text テキスト領域の開始

MIPS の練習

アセンブラのソース

Text領域

(命令コード)

データ領域

(命令コード)

実行結果 QtSpimの出力

.data

msg: .asciiz "Hello World"

.text

.globl main

main: li $v0, 4 # syscall 4 (print_str) la $a0, msg # argument: string syscall # print the string jr $ra # retrun to caller

スタートアップ

アセンブラ言語の形

mainの処理

#Text領域

#Data領域 .text

.globl main main:

jr $ra

.data _start:

jal main スタートアップルーチン、自動的に生成される

テキスト領域(プログラム領域)

データ領域

グローバル変数

疑似命令

セグメント、ラベル、データの宣言

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

例 .text[addr]

.data: データ領域の開始

.globl L: ラベル L を大局的に参照可能な記号と宣言する。

例 .globl main

.word n: 1 語のデータ n を配置。

.space n: n バイトの領域を確保

.asciiz "Strings": 文字列を配置。 ( 末尾に NULL 文字を追加 )

足し算の例

add.asm

# Text Segment

.text

.globl main main:

addi $a0,$zero,5 # a0=5 addi $a1,$zero,10 # a1=10 add $v0,$a0,$a1 # v0=a0+a1

jr $ra #main の終了

#Data Segment

.data

マクロ命令

レジスタの初期化

Li (Load Immediate) 命令

La (Load Address) 命令

la rs, addr 意味 rs <=addr (32bit)

move(Move) 命令

move rd, rs 意味 rd <=rs

実際の命令

li Rd, value

lui $at, Upper 16-bits of value ori Rd, $at, Lower 16-bits of value

la Rd, Label

lui $at, Upper 16-bits of Label ori Rd, $at, Lower 16-bits of Label

move Rd, Rs addu Rd, $0, Rs

実際の機械語では

16bitの即値しか扱えないので

2回に分ける

実際の機械語では

16bitの即値しか扱えないので

2回に分ける

自分のPCに QPSIM をインストールして実行できるようにしておくこと

MIPSのプログラミングについては下記URLが 参考になる。 その他日本語サイトも

アセンブラプログラムの開始

スタートアップ lw $a0 0($sp) addiu $a1 $sp 4 addiu $a2 $a1 4 sll $v0 $a0 2

addu $a2 #a2 $vo jal main

アセンブラプログラムの開始

lw $a0 0($sp)

addiu $a1 $sp 4 addiu $a2 $a1 4 sll $v0 $a0 2

addu $a2 #a2 $vo jal main

C 言語のmain関数の引数

main(argc, argv)

$4 arggc

$5 argv

$6 環境変数のポインタ

# シャープはコメントを表す. # このプログラムはa=b+cを実行する.

# a=$s0, b=$s1, c=$s2とする

# addi命令は第2オペランドに定数が書ける

# $zeroは常に値が0のレジスタ

# 最初に実行する関数はmainと決まっているのでmainを宣言する必要がある.

# .globl main

# main関数の宣言. main: addi $s1, $zero, 1

# b=$s1=1 addi $s2, $zero, 2

# c=$s2=2 add $s0, $s1, $s2

# a=$s0=b+c=3 jr $ra

# プログラムの終了

# a=$s0=3になっていることをSPIMシミュレータで確認すること

C のプログラムとアセンブラの比較 例題1

.globl main # main関数の宣言 main: addi $s1, $zero, 1 # b=$s1=1 addi $s2, $zero, 2 # c=$s2=2 add $s0, $s1, $s2 # a=$s0=b+c=3 jr $ra # end

C のプログラムとアセンブラの比較 例題1

C のプログラムとアセンブラの比較 例題 2

main() {int a, b, c;

b=-1;

c=2;

a=b+c;

}

.globl main # a=$s0, b=$s1, c=$s2

main: sub $s1, $zero, 1 # b=$s1=-1 add $s2, $zero, 2 # c=$s2=2

add $s0,$s1,$s2 # a=$s0=b+c=1

jr $ra #

.globl main # a=$s0, b=$s1, c=$s2 main: sub $s1, $zero, 1 # b=$s1=-1 add $s2, $zero, 2 # c=$s2=2 add $s0,$s1,$s2 # a=$s0=b+c=1 jr $ra #

C のプログラムとアセンブラの比較 例題 2

アセンブラプログラムの開始

lw $a0 0($sp)

addiu $a1 $sp 4 addiu $a2 $a1 4 sll $v0 $a0 2

addu $a2 #a2 $vo jal main

C 言語のmain関数の引数

main(argc, argv)

$4 arggc

$5 argv

$6 環境変数のポインタ

main(){

int a, b, c;

b=1;

c=2;

a=b+c;

printf("a=%d¥n) }

C のプログラムとアセンブラの比較 例題 4

# b=1, c=2 とし,a=b+cを計算する.

# その答えを a = 3 とプリントする.

# Data記述部でプリントする文字列を定義しておく.

# Data記述部

.data

str: .asciiz "a = "

.text # mainプログラムをテキストセグメントに置く.

.globl main # mainの宣言. a=$s0, b=$s1, c=$s2とする main: addi $s1, $zero, 1 # b=$s1=1

addi $s2, $zero, 2 # c=$s2=2 add $s0, $s1, $s2 # a=$s0=b+c

# プリントするためのプログラム

addi $v0, $zero, 4 # syscallに文字のprintを指示

la $a0, str # $a0に文字列str:のアドレスを入れる syscall # 文字列"a = "をプリント

add $a0, $s0, $zero # $a0=$s0

addi $v0, $zero, 1 # syscallに整数のprintを指示 syscall # aの値をプリント

jr $ra # プログラムの終了

C のプログラムとアセンブラの比較 例題 4

.data

str: .asciiz "a = "

.text

.globl main main: addi $s1, $zero, 1 addi $s2, $zero, 2 add $s0, $s1, $s2

# プリントするためのプログラム addi $v0, $zero, 4 la $a0, str syscall add $a0, $s0, $zero addi $v0, $zero, 1 syscall jr $ra

C のプログラムとアセンブラの比較 例題 4

Data segment の先頭アドレスが0x10010000, 0x1001=4097

la $a0, str lui $4, 4097[str]

1 0 0 1

$4レジスタ すなわち a0レジスタ 10進の4097は16進で1001 0 0 0 0

上位16bitに

16進の1001を格納

下位16bitは 0を入れる

マクロ命令の使われ方

C のプログラムとアセンブラの比較 例題 5

int x[2];

main() {

Int c;

x[0]=0;

x[1]=6;

c=5;

x[0]=x[1]+c}

.data

X: .word 0,6

# テキストセグメントを定義する.

.text

.globl main # main関数の宣言.

main:

la $s1, X # $s1に配列x[0]のアドレス

addi $s3, 5 # c=$s3=5

lw $s6, 4($s1) # $s6=x[1] $6x[1]をロード

# PCSpimでメニューのsimulator→settingsdelayed loadにチェックを入れると,

# lw命令は値をレジスタにロードするのに2サイクルかかるようになる.

# チェックをはずすとlw命令を1サイクルで実行する.

# ここではメモリが遅いためロードは2サイクルかかるとする.

# lw1サイクル後はレジスタにまだloadする値が入っていない.そこで意味のない

# 命令を実行してもう1サイクル時間を遅らせる.

add $t1, $t1, $zero # load delayのため1サイクル遅らせる

意味のない命令

ドキュメント内 計算機構成論II第4回-7回 (ページ 50-70)

関連したドキュメント