Noam Nisan, Shimon Schocken著『コンピュータシステムの理論と実装』(オライリー・ジャパン刊)の各章に用意されているプロジェクトの成果物
本書をがカバーするトピックは,モダンなコンピュータをゼロから作り上げる,という明確な目的のもとで組まれているが,トピックの数は最小限に抑えている.例えば,最適化という重要な問題についてはあまり注意を払っていない.
本書では,実践的な作業を通じて完全なコンピュータシステムをゼロから作り上げていく.まず基本となる論理ゲートから始め(1章),順序回路と組み合せ回路へと進む(2~3章).さらに一般的なコンピュータアーキテクチャを設計し(4~5章),一般的なソフトウェア階層を構築する(6~8章).そして,モダンなオブジェクトベースの言語(9章)のためのコンパイラを実装するに至る(10~11章).最終的にシンプルなOSの設計と実装を行う(12章).
最も単純な論理ゲートの1つであるNANDゲートから始め,その他全ての論理回路をNANDゲートから作成していく. 結果として,より一般的な論理回路ができあがり,後ほどコンピュータの処理とストレージ用の回路を作るときに用いられる.
数を表現し算術演算を行うための論理ゲートを作成する.出発点は1章で作成した論理ゲートであり,終着点は算術論理演算器(ALU)である.コンピュータで行われる算術演算と論理演算は全て,このALU回路によって行われる.そのため,ALUの機能を理解することは,CPUさらにはコンピュータ全体の仕組みを理解する上で重要なステップとなる.
コンピュータは値を計算するだけでなく,その値を呼び出すことができなければならない.そのため,時間が経過してもデータを記憶できる記憶素子を備える必要がある.この記憶素子は順序回路から構築できる.本章では,フリップフロップをプリミティブな構成要素として2値素子からレジスタ・メモリ・カウンタと順を追って構築していく.
新しいコンピュータシステムに慣れ親しむためには,機械語で書かれたプログラムをいくつか見るのが手っ取り早い.これは何か有用なことを実行する方法を理解するためだけでなく,ハードウェアがなぜそのように設計されているかを理解するためにも役立つ.その点を考慮して,本章では機械語による低水準のプログラミングに焦点を当てる.本章は次章のために前準備である.
1~3章までに作成した回路を用いて汎用コンピュータを構築する.この汎用コンピュータはメモリ(3章)に格納された機械語プログラム(4章)をALU(2章)を駆使して実行することができる.
ソフトウェア階層において最初のモジュールであり,最も基礎となるモジュールがアセンブラである.本章では,アセンブリ言語で書かれたプログラムを,5章で作成したハードウェアのプラットフォーム上で実行できるバイナリコードへと変換するアセンブラを開発する.
本章はコンパイラの構築へ向けた第一歩である.コンパイラを作るという作業は相当に困難であるため,本書ではそれを2段階に分けて取り組むことにする.この2つの段階にはそれぞれ2章が割かれ,合計で4章に渡る.本書で提示するVMはスタックをベースとしたものである.
本章と次章では,VMプログラムをアセンブリコードへと変換するVM変換器を実装する.VMプログラムを記述するためのVM言語には以下の4つのコマンドが含まれる.
- 算術コマンド
- メモリアクセスコマンド
- プログラムフローコマンド
- サブルーチン呼び出しコマンド
本章では前半2つのコマンドを変換するベーシックなVM変換器を実装する.次章で後半2つの機能を備えるように変換器を拡張する.結果として完全なVMができあがり,これは10~11章で作るコンパイラのバックエンドとして動くことになる.
前章から引き続きVM実装の開発を行う。特に,手続き型言語やオブジェクト指向言語のネスト化されたサブルーチン呼び出しを扱う。前章で構築した基本となるVM変換器を拡張し,完全版のVM変換器へと至る.
本章の目的はJack言語について慣れ親しみ,この先に待ち受けるコンパイラとオペレーティングシステムの開発に対して準備することである.単純なゲームやインタラクティブなプログラムなど,Jackで開発したいアプリケーションを考える。アプリケーション開発のガイドラインとして,4つのサンプルアプリケーションを紹介する。そして,考えたアプリケーションの設計と実装を行う.
コンパイルは概念的に構文解析とコード生成という2つの作業に基づいている.本章では,構文解析に焦点を当て,コード生成機能を備えない構文解析器を作る.本章の構文解析器だけのために独立してユニットテストを行うには,ソースプログラムを"理解している"ことを示す何らかの方法を考えなければならない.解決策として,ここではXMLファイルを出力させる方法を採用した.
10章で作った構文解析器を拡張し,完全版のJackコンパイラを完成させる.具体的には,XMLコードを生成するモジュールを,実行可能なVMコードを生成するモジュールへと段階的に置き換える.
Jackを用いて簡単なOSを実装する.本章で目標とするOSはミニマルな構成であり,提供するサービスも最小限に抑えてある.このOSは,次の2つのことを目標として設計されている.
- ハードウェアに特化したサービスをカプセル化し,ソフトウェアから使いやすいサービスを提供すること.
- 高水準言語を様々な関数と抽象データで拡張すること.
このOSはJackの標準ライブラリとしてパッケージされ,それぞれがJackのサブルーチン呼び出しを通して関連するサービスを提供する.結果としてできあがるOSは商用のOSと似た特徴を持つが,プロセス処理やディスク管理,通信などといった商用OSが持つ機能を欠いている.
読者が修正や拡張を行えるようにするために,本書で使用したソフトウェアは全て,そのソースコード(Java)をオープンソースとして公開されている.ソフトウェアおよびドキュメントは,本書のWebサイトから取得できる.本章では,筆者らが思いつく設計案がいくつか紹介されている.
本書で提示したハードウェアモジュールは全てHDLでシミュレートしたものであった.しかし,このHDLによる設計図をシリコンへと移し,"本物のコンピュータ"として動かすことも不可能ではない.
現時点のHackアーキテクチャにおいては,物理的なROM回路を丸ごと取り替える以外に,ユーザ操作によって別のプログラムをコンピュータに読み込む方法はない.
本書で開発したJack言語には不満な点がたくさん残されている.例えば,Jackはオブジェクト指向の言語であるが,「継承」をサポートしていない.
本書では「最適化」について,そのほとんどを省略した. 最適化は,全てのハッカーにとって"偉大なる競技場"である.
Hackコンピュータをインターネットにつなぐことができたとすれば,素敵なことではないだろうか.そのためには,ビルトインの通信回路をハードウェアに追加し,高水準の通信プロトコルを扱うためのコードを書く必要があるだろう.