コマ0: 演習環境構築
この回の位置づけ
番号のある通常回には含めない、授業開始前の準備回である。 初回授業の開始時点で、この回の内容が終わっている状態を目標にする。 分からないところが残ったまま来てもよいが、どこで止まったかを言えるようにしておく。
ゴール
qemu 上で手書き RV64 アセンブリを実行し、終了コード 42 を確認する。
この回ではコンパイラのコードは書かない。まずは RISC-V アセンブリを手で書いて、
アセンブル・リンク・実行の流れを理解する。
必要なもの
- Python 3.10 以降(
match文、str | Noneのような合併型注釈を使う)。 Docker 環境・ネイティブ実行のどちらでも必要になる基準である - RV64 クロスコンパイラ
riscv64-linux-gnu-gcc qemu-riscv64
Docker 環境(docker/rv64/)を使えば、この3つはすべて入った状態で始められる。
Python 3.10 以降という基準は、この節が教材全体を通じての唯一の出典である (他の文書ではここを参照すること)。
1. Windows の場合: WSL 上に Ubuntu を入れる
macOS・Linux を使う場合はこの節を読み飛ばし、「2. 演習環境を用意する」へ進む。
対象は Windows 10 バージョン 2004 以降、または Windows 11。 以下は画面写真を載せていない。Windows のバージョンで表示が変わるためで、 コマンドの出力そのものを確認の手がかりにする。
手順
スタートメニューから PowerShell を「管理者として実行」 で開く。
Ubuntu 22.04 をインストールする。
wsl --install -d Ubuntu-22.04指示に従って PC を再起動する。
再起動後に自動で開く Ubuntu のウィンドウで、ユーザー名とパスワードを設定する。 このパスワードは Windows のものとは別で、
sudoを使うときに聞かれる。パッケージを最新にする。
sudo apt update sudo apt upgrade -y
Ubuntu 22.04 を指定するのは、標準の python3 が 3.10 で上の基準を満たすためである。
入ったことの確認
Ubuntu のウィンドウで次を実行する。
lsb_release -d # → Description: Ubuntu 22.04...
python3 --version # → Python 3.10 以降以降の作業はすべて、この Ubuntu の中で行う。 Windows 側のファイルではなく、Ubuntu のホームディレクトリに演習用のファイルを置くこと。
2. 演習環境を用意する
配布物と作業場所を確認する
ここからは、入手・展開済みの配布物 workbook/ を使う。
まだ配布物が手元に無い場合は、教員から案内された入手先を確認する。
ターミナルで配布物の親ディレクトリへ移動し、次を実行する
(WindowsではWSLのUbuntu、macOS・Linuxではホストのターミナルを使う)。
cd workbook
ls sessions/00_setup/hello.s docker/rv64/run.sh2つのファイルが表示されれば作業場所は正しい。
以降のコマンドは、この workbook/ から実行する。
Dockerコンテナ内では同じディレクトリが /work として見える。
推奨は Docker である。RV64 クロスコンパイラと qemu が入った環境が用意してある
(Ubuntu 22.04 ベースなので、コンテナ内の python3 は 3.10 を満たす)。
Docker 自体を入れる
macOSでは、Docker公式のインストール手順
から、Apple silicon/Intelのどちらか自分のMacに合うDocker Desktopを入れる。
Docker.dmgを開いてDockerをApplicationsへ移し、ApplicationsからDockerを起動する。
初回の案内に従って起動を完了したら、ホストのターミナルで docker ps を実行する。
コンテナ一覧が表示されれば準備完了である(何も起動していなければ見出しだけでよい)。
Ubuntu(WSL の中でも同じ)では、Docker がまだ無い場合に次を実行する。
sudo apt update
sudo apt install -y curl
curl -fsSL https://get.docker.com | sh
sudo usermod -aG docker $USERusermod の後は一度ログアウトして入り直す(WSL なら Ubuntu のウィンドウを閉じて開き直す)。
docker ps が権限エラーにならずに実行できれば準備完了である。
以下は workbook/ から実行する。
# コンテナ起動(初回はイメージをビルド)
bash docker/rv64/run.sh
# 完成済みの命令例で実行環境だけを確認する(1回のコンテナ起動でコンパイルと実行)
bash docker/rv64/run.sh sh -c 'riscv64-linux-gnu-gcc -static sessions/00_setup/tests/sub.s -o /tmp/rv64_smoke && qemu-riscv64 /tmp/rv64_smoke'
echo $? # → 42後の回でテストをまとめて走らせるときも、同じ形で使う。
bash docker/rv64/run.sh python3 scaffold/test_runner.pyネイティブ実行も許可する。その場合は Python 3.10 以降に加えて
riscv64-linux-gnu-gcc と qemu-riscv64 がホストに必要になる。
Ubuntu なら次で入る。
sudo apt install gcc-riscv64-linux-gnu qemu-user python3イメージ名の変更やよくあるエラーは docker/rv64/README.md を参照。
3. 手書きアセンブリを動かす
Step 1: hello.s を書く
配布される sessions/00_setup/hello.s は終了コード 0 を返す未完成starterである。
このファイルの 0 を 42 に変更して、以下の内容にする。
.global main
main:
addi a0, zero, 42 # 戻り値 = 42
retStep 2: コンパイルして実行
Dockerを使っている場合は、ホストの workbook/ から
bash docker/rv64/run.sh でコンテナのシェルを開く。
次のコマンドはコンテナ内の /work、またはネイティブ環境の workbook/ から実行する。
riscv64-linux-gnu-gcc -static sessions/00_setup/hello.s -o hello
qemu-riscv64 ./hello
echo $? # → 4242 が表示されれば成功。
この演習で作るのは、図の hello.s にあたる「アセンブリを出力する部分」=コンパイラ本体である。
自作コンパイラ mycc.py がこの部分を出力するようになるのは、コード生成の回からである。
Step 3: 確認スクリプト
Step 2と同じシェルで実行する。
python3 sessions/00_setup/check.py[PASS] が3件表示され、echo $? が 0 になればコマ0は完了である。
編集前のstarterでは hello.s だけが [FAIL] となり、終了コードは 1 になる。
完成済みの追加例2件が通っていれば、これを環境故障と取り違えないこと。
Step 4: もっと複雑な計算
tests/ には完成済みの命令例が置いてある(一覧は後の「tests/」節を参照)。
編集対象ではないので、addi / li / add などの基本命令の組み合わせを読んで確認する。
編集するファイル
sessions/00_setup/hello.s(workbook/からの相対パス)
最初に addi a0, zero, 0 を終了コード 42 を返す命令へ変更する。
tests/
編集対象は sessions/00_setup/hello.s であり、check.py はこれを直接検査する。
tests/hello.s は hello.s の完成形の参照であり、check.py の検査対象には含まれない
(同名だが別ファイルである点に注意)。
tests/ 以下で check.py が実際に検査するのは次の2件で、どちらも完成済みの命令例であり編集対象ではない。
| ファイル | 内容 | 期待値 |
|---|---|---|
sub.s |
50 + (-8) で減算相当 |
42 |
three_numbers.s |
10 + 20 + 12 で 3 数の和 |
42 |
テスト
python3 sessions/00_setup/check.pyこのコマンドは、編集した hello.s と完成済みの追加例2件をまとめて確認する。
個別に動かす場合は、次のようにする。
riscv64-linux-gnu-gcc -static sessions/00_setup/hello.s -o out
qemu-riscv64 ./out
echo $?終了コードが 42 になれば成功である。
全3件の確認が済んだら、コマ1: ASTの仕組みとインタープリーターへ進む。
注意
終了コードは 0〜255 の範囲しか返せない。
echo $? の値が合わないときは、a0 に値を入れる命令が ret より前にあるか、
ret を書き忘れていないかを確認する。
.global main を消すとリンクに失敗する。libc の起動処理が main を呼ぶためである。
おまけ: OpenCode
ターミナルで動く AI コーディングアシスタント OpenCode を入れておくと、 実装中の疑問を相談できる。必須ではないので、環境構築が終わってから余裕があれば入れればよい。
インストール手順と使い方は OpenCode 導入ガイド にまとめてある。 教員の代わりにはならないこと、生成されたコードは必ず自分で理解してテストで確認することの 2点だけ先に押さえておく。