クリーム色の背景、色付き表示、高コントラスト、大きな文字のほうが読みやすいですか?配色と文字を選ぶと、すべてのページに一度で反映されます。

無料レッスン

コンピュータアーキテクチャの基礎

レッスン全文をここで読めます。無料アカウントを作成すると、実際のラボで実践できます。

仮想マシンラボ読了目安 12分コマンド10個

持っていないプロセッサ用のプログラム

スマートフォン、ノートパソコン、サーバーは、それぞれ違うプロセッサを使っています。プロセッサは、自分の命令しか分かりません。RISC-V は、だれでも作ってよい公開の設計です。このマシンは RISC-V ではありませんが、エミュレータを使えば RISC-V のプログラムを動かせます。

このレッスンが終わると

メモ

短い RISC-V のプログラムを、アセンブリから終了ステータスまでたどることができる。

キーワード

  • プロセッサ:コンピュータの中で命令を実行する部分。
  • 命令:プロセッサができる小さな1歩。足し算など。
  • レジスタ:プロセッサの中にある、ごく小さく速い記憶場所。
  • エミュレータ:別のプロセッサのようにふるまうプログラム。
  • 終了ステータス:プログラムが終わるときに返す数。
  • キャッシュ:最近使ったものを置いておく、小さく速いメモリ。

ウォームアップ:すでに知っていること

メモ

頭の中で答えてみましょう。1. コンパイラはソースコードを何に変えますか。2. 機械語をつないで1つのプログラムにするのは、どの段階ですか。3. アセンブリとは何ですか。今日は、人が書いたアセンブリを読みます。

はじめる前に

メモ

このレッスンの上にあるバーのラボを起動を押してください。このラボは、あなた専用の Ubuntu のマシンまるごとです。コンテナよりも、立ち上がるまで少し時間がかかります。実行ボタンを押すと、コマンドが順番にマシンのターミナルへ入力されます。「マシンはまだ起動中です」と出たら、数秒待ってからもう一度押してください。自分で入力と書かれたところでは、プログラムがあなたの入力を待ちます。バーのターミナルを開くを押して、自分で打ち込みます。

RISC-V のプログラムを1行ずつ

add.s には命令が5つあります。li はレジスタに数を入れます。a0 に 2、a1 に 3 です。add は2つを足し、答えを a0 に入れます。li a7, 93 はプログラムを終わらせる Linux のシステムコールを選び、ecall がそれを呼びます。Linux は a0 の数を終了ステータスにします。

コマンド
cd ~/arch

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
cat add.s

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

チェック

ヒント

add a0, a0, a1 の後、a0 には何が入っていますか。答え: 5。2 と 3 の和です。

組み立てて、エミュレータで動かす

アセンブラが言葉を機械語に変え、リンカがプログラムにします。file は、これが RISC-V 用だと示します。このプロセッサでは動かせないので、qemu-riscv64 が RISC-V の命令を1つずつ実行します。何も表示されません。echo $? が、プログラムの残した終了ステータス 5 を表示します。

コマンド
riscv64-linux-gnu-as add.s -o add.o

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
riscv64-linux-gnu-ld add.o -o add

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
file add

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
qemu-riscv64 ./add

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
echo $?

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

よくある間違い

注意

echo $? はプログラムが最後に表示したものを出す、と考える人がよくいます。実際に出すのは終了ステータスで、プログラムが終わるときに返す 0 から 255 までの数です。2 と 3 を 200 と 100 に変えて組み立て直すと、答えは 44 になります。300 は入りきらず、0 に戻って数え直すからです。

命令は数である

objdump -d は、プロセッサから見たプログラムを表示します。各行は、アドレス、16進数で書いた命令、言葉で書いた命令の順です。どの数も16進数で8けたです。ここにある命令は、どれも32ビットだからです。ecall は 00000073 です。

コマンド
riscv64-linux-gnu-objdump -d add

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

キャッシュがメモリを速く見せる

loop.c は、1600万個の数の表を2回足し合わせます。行ごとに進むと、次の数はメモリ上で前の数のすぐ隣にあり、キャッシュがもう読み込んでいます。列ごとに進むと、次の数は 16 KB 先にあるので、プロセッサはほぼ毎回メモリを待ちます。合計はどちらも 16777216 ですが、時間は違います。列ごとのほうが何倍もかかります。

コマンド
gcc -O2 -o loop loop.c

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

コマンド
./loop

ここでは表示のみで、実行されません。無料アカウントを作成すると、実行ボタンで自分のラボのターミナルに入力できます。

自分で入力:プロセッサが進むのを見る

ターミナルで gdb ./loop と打ちます。break main、続けて run と打つと、プログラムは main の最初で止まります。info registers pc と打つと、次の命令のアドレスであるプログラムカウンタ(pc)が見えます。stepi で命令を1つだけ実行し、もう一度 pc を見てください。先へ進んでいます。最後に quit、続けて y と打ちます。

最後のチェック

ヒント

前を見ないで答えましょう。1. レジスタとは何ですか。2. このマシンで RISC-V のプログラムを動かすコマンドはどれですか。3. echo $? は何を表示しますか。4. 行ごとのほうが速いのはなぜですか。答え: プロセッサの中の、ごく小さく速い記憶場所。qemu-riscv64。直前のコマンドの終了ステータス。次の数がもうキャッシュにあるから。

先生へ

ヒント

このレッスンは VM ラボで行います。学生はそれぞれ自分の Ubuntu マシンを持ち、実行ボタンはそのターミナルに入力して、表示された結果を見せます。学習のポイント:1. プロセッサは、レジスタを使う命令を実行する。2. アセンブラとリンカがアセンブリをプログラムにし、エミュレータがそれを別のプロセッサ用に動かす。3. 直前に読んだ場所の近くのメモリは、キャッシュのおかげで速い。よくある間違い:終了ステータスを、プログラムの表示だと思ってしまう。準備するもの:ラボとブラウザ。ヒント:./loop の前に、どちらが速いか、どれくらい違うかをクラスに予想させてください。このラボには検査がなく、採点もしません。成績が必要なら、独自の提出物を出してください。

このラボのほかのレッスン

このラボとソースについて: コンパイラとアーキテクチャのラボ:gcc、flex、bison、RISC-V を1台の VM で

授業で教えていますか?これらのレッスンを生徒に割り当て、採点と生徒ごとのラボを使えます。