Presentation is loading. Please wait.

Presentation is loading. Please wait.

1 B10 CPU を作る 1 日目 解説 TA 高田正法

Similar presentations


Presentation on theme: "1 B10 CPU を作る 1 日目 解説 TA 高田正法"— Presentation transcript:

1 1 B10 CPU を作る 1 日目 解説 TA 高田正法 mtakada@mtl.t.u-tokyo.ac.jp

2 2 はじめに 下のページに目を通すようにしてくださ い。  http://www.mtl.t.u- tokyo.ac.jp/~mtakada/jikken_b10/ http://www.mtl.t.u- tokyo.ac.jp/~mtakada/jikken_b10/  このスライドも上記の場所にあります。

3 3 今日説明する内容 実験の目的、内容 この実験で扱う道具について  SPIM  MIPS アーキテクチャ 課題 1 ~ 3 を行うために必要な知識  レジスタ  命令  システムコール MIPS 用プログラム記述の例

4 4 実験の目的 RISC 型プロセッサの構造、動作を理解す る  命令セットを理解する  命令を MIPS シミュレータ ”SPIM” に追加する ことによって、プロセッサの動作に関する理 解を深める

5 5 実験の内容 MIPS の命令セットを理解する  アセンブラでプログラムを書く 課題 1 ~ 3 プロセッサの動作を理解する  構成図を見て考える 課題 4 ~ 5,8  シミュレータを用いて、命令追加を行う 課題 6 ~ 7  シミュレータと実機の違いについて考える 課題 8

6 6 SPIM とは? RISC プロセッサ MIPS R2000 のシミュ レータ 以下の機能をサポート  アセンブリ言語からの直接読み込み  プロセッサの状態表示  ステップ実行  簡単な入出力

7 7 MIPS とは? RISC 型プロセッサの一種  機能が単純な命令のみを持ち、複雑な機能は 命令の組み合わせでサポートする  メモリを扱う命令が、他の命令と分離されて いるのが特徴 32 個の 32bit レジスタを持つ  レジスタ : 計算をするための作業領域

8 8 メモリとレジスタの違い メモリ  ○ 大きい (2^32Byte など )  ○ アクセスする領域 ( アドレス ) も変数  × 演算命令で直接扱えない  × 遅い レジスタ  ○ 演算命令で直接扱える  ○ 速い  × 小さい (32bit レジスタが 32 個 )  × アクセスする領域 ( レジスタ番号 ) は命令内で明示

9 9 レジスタの種類 (1) – 汎用レジス タ $t0 ~ $t9  ユーザー用のレジスタ  サブルーチン ( 関数 ) を呼び出す際には、呼び 出す側で値を保存しておく必要がある $s0 ~ $s7  ユーザー用のレジスタ  呼び出されたサブルーチン側で、中身を保存 する必要がある

10 10 レジスタの種類 (2) – 関数呼び出し 用 $a0 ~ $a3  サブルーチン ( 関数 ) を呼び出す際に、引数を これに入れる $v0 ~ $v1  サブルーチン ( 関数 ) からの戻り値をここに入 れる $ra  サブルーチン ( 関数 ) を呼び出した側の、プロ グラム番地を保存する

11 11 レジスタの種類 (3) – 特殊なレジス タ $zero  常に 0 が入っているレジスタ $sp  スタックの先頭のアドレスが格納されるレジ スタ

12 12 レジスタの種類 (4) – 使わないもの 使ってはいけないレジスタ  $at 疑似命令を展開する時に使われるレジスタ ここでいう疑似命令 : ソースファイルに書くことが可能であ るが、実際には複数の実在する命令に展開される命令のこと ( 例 :blt)  $k0 ~ $k1 OS 予約レジスタ 気にしなくて良いレジスタ  $gp, $fp

13 13 プロセッサの命令の種類 メモリ ←→ レジスタのデータのやり取りをする 命令  いわゆる load/store レジスタを用いて計算をする命令  算術演算、論理演算その他 次に実行する命令を変える命令  条件分岐命令 C 言語の if, for, while などで使われる  無条件ジャンプ命令 C 言語での関数呼び出しなどで使われる

14 14 lw$t0, 4($t1)  メモリの ($t1 + 4) 番地に書かれている値 (32bit) を、 $t0 レジスタに格納する  $t0 = *($t1 + 1); +1 なのは、 +4 番地 =32bit 向こう =1 要素進んだところだから sw$s2, 0($t0)  $s2 の中身 (32bit) を、メモリの ($t0+0) 番地に格納する  *($t0) = $s2; load/store の例 1Byte 1Word(32bit) x x+1 x+2 x+3 x+4…( 番地 ) 1Word(32bit)

15 15 演算命令の例 addi$t0, $t1, 1  $t0 = $t1 + 1; or$s0, $s1, $s2  $s0 = $s1 | $s2;

16 16 制御命令の例 bne$t0, $t1, LABEL  $t0 != $t1 ならば、次からは、 LABEL 番地か ら始まる命令列を実行する  if( $t0 != $t1 ) goto LABEL; jalLABEL  $ra に、 jal 命令の番地 +4 を格納し、次からは LABEL 番地から始まる命令列を実行する  サブルーチン ( 関数 ) 呼び出しに使われる

17 17 syscall の使い方 SPIM では、キーボードからの入力 / 画面へ の出力を、 syscall を使って行います $v0 にシステムコール番号を入れることに よって、数種類の機能を実現できます 詳しくは、 SPIM マニュアルの 8 ページを 参照してください

18 18 システムコールの例 $t0( 整数型 ) の中身を画面に表示  li$v0, 1# $v0 = 1;  move$a0, $t0# $a0 = $t0;  syscall メモリの $t0 番地から始まる文字列を表示  li$v0, 4# $v0 = 4;  move$a0, $t0# $a0 = $t0;  syscall プログラムの実行を終了  li$v0, 10  syscall

19 19 MIPS 用プログラム の記述例

20 20 具体例 このような関数を考えましょう  num という配列が渡されたときに、先頭 n 要素の和を返す関数 int sum(int n, int num[]){ int sum = 0; int i; for( i = 0; i < n; i++ ){ sum += num[i]; } return sum; }

21 21 C 言語からアセンブリ言語へ C 言語の変数は、主に 2 種類  static 変数 プログラムのどこからでも見ることのできる変数 コンパイル時に、静的にメモリに割り当てられる  local 変数 同じ関数内でのみ参照可能 実際には以下のいずれかに割り当てます  レジスタ ← ほとんどこちらだけで事足ります  メモリのスタック領域(※坂井先生の資料 8 ページ参照)

22 22 ソースファイルの書式.data# お約束 ここに、 static 変数に対応する部分を ”.word” 等の疑似命令を使って書く.text# お約束.globlmain# お約束 main:# お約束 ここからプログラムを書く # “#” から行末まではコメントになります

23 23 for 文の展開 for( i = 0; i < n; i++) をアセンブリ言語で書きま しょう n は、 $a0 に入っていると仮定 i は $t0 に割り当てましょう li$t0, 0# i = 0; loop_start: 何か処理 … addi$t0, $t0, 1# i++ bne$t0, $a0, loop_start# if( i != n ) goto loop_start;

24 24 メモリからの読み出し $a1 に、先頭の要素のアドレスが入っていると仮定しましょう $t1 に、現在の要素のアドレスを入れましょう $t2 に、各要素の値を一時的に格納しましょう $v0 に、合計の値を格納しましょう li$t0, 0# i =0; li$v0, 0# sum = 0; move$t1, $a1# $t1 = $a1; loop_start: lw$t2, 0($t1)# $t2 = *($t1); add$v0, $v0, $t2# $v0 = $v0 + $t2; addi$t1, $t1, 4# 次の要素は 4 番地 (32bit) 先 addi$t0, $t0, 1# i++; bne$t0, $a0, loop_start# if( I != n ) goto loop_start;

25 25 関数ができました sum: li$t0, 0# i =0; li$v0, 0# sum = 0; move$t1, $a1# $t1 = $a1; loop_start: lw$t2, 0($t1)# $t2 = *($t1); add$v0, $v0, $t2# $v0 = $v0 + $t2; addi$t1, $t1, 4# 次の要素は 4 番地 (32bit) 先 addi$t0, $t0, 1# i++; bne$t0, $a0, loop_start# if( i != n ) goto loop_start; jr$ra# 関数呼び出し元へ

26 26 この関数の仕様 配列に入っている各要素の和を計算する  $a0: 要素数  $a1: 先頭のアドレス  $v0: 計算結果

27 27 呼び出し元を書きましょう こんなプログラムだとしましょう int numOfElements=4;// static 変数 int elements[] = {1, 2, 3, 4};// static 変数 void main(){ int s = sum( numOfElements, elements); printf( “%d”, s); }

28 28 呼び出し元 main: lw$a0, numOfElements# $a0 = numOfElements; la$a1, elements# $a1 = &(elements[0]); jalsum# $v0 = sum($a0, $a1); move$a0, $v0# $a0 = s; li$v0, 1# syscall# prinf(“%d”, s); li$v0, 10 syscall# exit();

29 29 static 変数部分 今回は、 numOfElements と elements が static 変数.data numOfElements:.word 4# int numOfElements=4; elements:.word 1, 2, 3, 4# int elements[]={1, 2, 3, 4}; これで、 numOfElements が ”4” の入ったアド レス、 elements が 1, 2, 3, 4 が入ったメモリ の先頭のアドレスを指すようになります

30 30 完了 http://www.mtl.t.u- tokyo.ac.jp/~mtakada/jikken_b10/ にある sum.s がこのプログラムの完成品です http://www.mtl.t.u- tokyo.ac.jp/~mtakada/jikken_b10/ SPIM で読み込んで、実行してみましょう .word 部分の値を変えて、結果が変わることを 確認してみましょう

31 31 駆け足になりましたが 各内容についての詳細は以下を参照してくださ い  レジスタの一覧 SPIM マニュアル 10 ページ  命令の一覧 SPIM マニュアル 13 ページ~  システムコールの一覧 SPIM マニュアル 8 ページ~ .data 部分に書くことのできるもの SPIM マニュアル 7 ページ~


Download ppt "1 B10 CPU を作る 1 日目 解説 TA 高田正法"

Similar presentations


Ads by Google