B10 cpu 1 l.jpg
This presentation is the property of its rightful owner.
Sponsored Links
1 / 31

B10 CPU を作る 1 日目 解説 PowerPoint PPT Presentation


  • 158 Views
  • Uploaded on
  • Presentation posted in: General

B10 CPU を作る 1 日目 解説. TA 高田正法 [email protected] はじめに. 下のページに目を通すようにしてください。 http://www.mtl.t.u-tokyo.ac.jp/~mtakada/jikken_b10/ このスライドも上記の場所にあります。. 今日説明する内容. 実験の目的、内容 この実験で扱う道具について SPIM MIPS アーキテクチャ 課題 1 ~ 3 を行うために必要な知識 レジスタ 命令 システムコール MIPS 用プログラム記述の例. 実験の目的.

Download Presentation

B10 CPU を作る 1 日目 解説

An Image/Link below is provided (as is) to download presentation

Download Policy: Content on the Website is provided to you AS IS for your information and personal use and may not be sold / licensed / shared on other websites without getting consent from its author.While downloading, if for some reason you are not able to download a presentation, the publisher may have deleted the file from their server.


- - - - - - - - - - - - - - - - - - - - - - - - - - E N D - - - - - - - - - - - - - - - - - - - - - - - - - -

Presentation Transcript


B10 cpu 1 l.jpg

B10 CPUを作る1日目 解説

TA 高田正法

[email protected]


Slide2 l.jpg

はじめに

  • 下のページに目を通すようにしてください。

    • http://www.mtl.t.u-tokyo.ac.jp/~mtakada/jikken_b10/

    • このスライドも上記の場所にあります。


Slide3 l.jpg

今日説明する内容

  • 実験の目的、内容

  • この実験で扱う道具について

    • SPIM

    • MIPSアーキテクチャ

  • 課題1~3を行うために必要な知識

    • レジスタ

    • 命令

    • システムコール

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


Slide4 l.jpg

実験の目的

  • RISC型プロセッサの構造、動作を理解する

    • 命令セットを理解する

    • 命令をMIPSシミュレータ”SPIM”に追加することによって、プロセッサの動作に関する理解を深める


Slide5 l.jpg

実験の内容

  • MIPSの命令セットを理解する

    • アセンブラでプログラムを書く

      • 課題1~3

  • プロセッサの動作を理解する

    • 構成図を見て考える

      • 課題4~5,8

    • シミュレータを用いて、命令追加を行う

      • 課題6~7

    • シミュレータと実機の違いについて考える

      • 課題8


Slide6 l.jpg

SPIMとは?

  • RISCプロセッサ MIPS R2000のシミュレータ

  • 以下の機能をサポート

    • アセンブリ言語からの直接読み込み

    • プロセッサの状態表示

    • ステップ実行

    • 簡単な入出力


Slide7 l.jpg

MIPSとは?

  • RISC型プロセッサの一種

    • 機能が単純な命令のみを持ち、複雑な機能は命令の組み合わせでサポートする

    • メモリを扱う命令が、他の命令と分離されているのが特徴

  • 32個の32bitレジスタを持つ

    • レジスタ:計算をするための作業領域


Slide8 l.jpg

メモリとレジスタの違い

  • メモリ

    • ○ 大きい(2^32Byteなど)

    • ○ アクセスする領域(アドレス)も変数

    • × 演算命令で直接扱えない

    • × 遅い

  • レジスタ

    • ○ 演算命令で直接扱える

    • ○ 速い

    • × 小さい(32bitレジスタが32個)

    • × アクセスする領域(レジスタ番号)は命令内で明示


Slide9 l.jpg

レジスタの種類(1) – 汎用レジスタ

  • $t0~$t9

    • ユーザー用のレジスタ

    • サブルーチン(関数)を呼び出す際には、呼び出す側で値を保存しておく必要がある

  • $s0~$s7

    • ユーザー用のレジスタ

    • 呼び出されたサブルーチン側で、中身を保存する必要がある


Slide10 l.jpg

レジスタの種類(2) – 関数呼び出し用

  • $a0~$a3

    • サブルーチン(関数)を呼び出す際に、引数をこれに入れる

  • $v0~$v1

    • サブルーチン(関数)からの戻り値をここに入れる

  • $ra

    • サブルーチン(関数)を呼び出した側の、プログラム番地を保存する


Slide11 l.jpg

レジスタの種類(3) – 特殊なレジスタ

  • $zero

    • 常に0が入っているレジスタ

  • $sp

    • スタックの先頭のアドレスが格納されるレジスタ


Slide12 l.jpg

レジスタの種類(4) – 使わないもの

  • 使ってはいけないレジスタ

    • $at

      • 疑似命令を展開する時に使われるレジスタ

      • ここでいう疑似命令: ソースファイルに書くことが可能であるが、実際には複数の実在する命令に展開される命令のこと(例:blt)

    • $k0~$k1

      • OS予約レジスタ

  • 気にしなくて良いレジスタ

    • $gp, $fp


Slide13 l.jpg

プロセッサの命令の種類

  • メモリ←→レジスタのデータのやり取りをする命令

    • いわゆるload/store

  • レジスタを用いて計算をする命令

    • 算術演算、論理演算その他

  • 次に実行する命令を変える命令

    • 条件分岐命令

      • C言語のif, for, whileなどで使われる

    • 無条件ジャンプ命令

      • C言語での関数呼び出しなどで使われる


Load store l.jpg

load/storeの例

1Word(32bit)

1Word(32bit)

1Byte

1Byte

1Byte

1Byte

1Byte

1Byte

1Byte

1Byte

x x+1 x+2 x+3 x+4…(番地)

  • 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;


Slide15 l.jpg

演算命令の例

  • addi$t0, $t1, 1

    • $t0 = $t1 + 1;

  • or$s0, $s1, $s2

    • $s0 = $s1 | $s2;


Slide16 l.jpg

制御命令の例

  • bne$t0, $t1, LABEL

    • $t0 != $t1 ならば、次からは、LABEL番地から始まる命令列を実行する

    • if( $t0 != $t1 ) goto LABEL;

  • jalLABEL

    • $raに、jal命令の番地+4を格納し、次からはLABEL番地から始まる命令列を実行する

    • サブルーチン(関数)呼び出しに使われる


Syscall l.jpg

syscallの使い方

  • SPIMでは、キーボードからの入力/画面への出力を、syscallを使って行います

  • $v0にシステムコール番号を入れることによって、数種類の機能を実現できます

  • 詳しくは、SPIMマニュアルの8ページを参照してください


Slide18 l.jpg

システムコールの例

  • $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


Slide19 l.jpg

MIPS用プログラムの記述例


Slide20 l.jpg

具体例

  • このような関数を考えましょう

    • numという配列が渡されたときに、先頭n要素の和を返す関数

      int sum(int n, int num[]){

      int sum = 0;

      int i;

      for( i = 0; i < n; i++ ){

      sum += num[i];

      }

      return sum;

      }


Slide21 l.jpg

C言語からアセンブリ言語へ

  • C言語の変数は、主に2種類

    • static変数

      • プログラムのどこからでも見ることのできる変数

      • コンパイル時に、静的にメモリに割り当てられる

    • local変数

      • 同じ関数内でのみ参照可能

      • 実際には以下のいずれかに割り当てます

        • レジスタ ←ほとんどこちらだけで事足ります

        • メモリのスタック領域(※坂井先生の資料8ページ参照)


Slide22 l.jpg

ソースファイルの書式

.data#お約束

ここに、static変数に対応する部分を

”.word”等の疑似命令を使って書く

.text#お約束

.globlmain#お約束

main:#お約束

ここからプログラムを書く

# “#”から行末まではコメントになります


Slide23 l.jpg

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;


Slide24 l.jpg

メモリからの読み出し

  • $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;


Slide25 l.jpg

関数ができました

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# 関数呼び出し元へ


Slide26 l.jpg

この関数の仕様

  • 配列に入っている各要素の和を計算する

    • $a0: 要素数

    • $a1: 先頭のアドレス

    • $v0: 計算結果


Slide27 l.jpg

呼び出し元を書きましょう

  • こんなプログラムだとしましょう

    int numOfElements=4;// static変数

    int elements[] = {1, 2, 3, 4};// static変数

    void main(){

    int s = sum( numOfElements, elements);

    printf( “%d”, s);

    }


Slide28 l.jpg

呼び出し元

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();


Static l.jpg

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が入ったメモリの先頭のアドレスを指すようになります


Slide30 l.jpg

完了

  • http://www.mtl.t.u-tokyo.ac.jp/~mtakada/jikken_b10/にあるsum.sがこのプログラムの完成品です

  • SPIMで読み込んで、実行してみましょう

    • .word部分の値を変えて、結果が変わることを確認してみましょう


Slide31 l.jpg

駆け足になりましたが

  • 各内容についての詳細は以下を参照してください

    • レジスタの一覧

      • SPIMマニュアル 10ページ

    • 命令の一覧

      • SPIMマニュアル 13ページ~

    • システムコールの一覧

      • SPIMマニュアル 8ページ~

    • .data部分に書くことのできるもの

      • SPIMマニュアル 7ページ~


  • Login