「コンピュータシステムの理論と実装」を読んだメモを書いていきます。
前回は↓
メモ
プログラムフロー
- goto
- 指定したアドレスやラベルにjumpする
- if-goto
- スタックの最上位の値を条件としてtrueの場合指定したアドレスやラベルにjumpする
サブルーチン
- システムやユーザによって実装された命令
- メソッド、プロシージャ、関数など
- サブルーチンを呼び出すと、低レイヤでは以下が行われる
- 呼び出し側からサブルーチンへ引数を渡す
- サブルーチン実行前に呼び出し側の状態を保存する
- サブルーチンのローカル変数のためのメモリを確保する
- サブルーチンを実行する
- サブルーチンから呼び出し側へ値を返す
- サブルーチンによって使われたメモリを再利用できるようにする
- 呼び出し側の状態を復帰させる
- サブルーチンの次の場所に実行を移す
- サブルーチン呼び出し
- ビルトインのコマンドと同じようにサブルーチンを呼び出す
- サブルーチンはローカル変数を使うことが一般的
- サブルーチンが生きている間はローカル変数が使える
- ネストしたサブルーチンや再帰呼び出しの場合も、呼び出し側の情報をスタックにpushしたあとに呼び出された側を処理すれば簡単に実装できる
- ワーキングスタック
- add,subなどの算術/論理演算やpush,popなどスタックに対する命令をサポートするためのメモリ領域
- グローバルスタック
- 処理中のサブルーチンとreturnを待つ他のすべてのサブルーチンのためのメモリ領域
- リターンアドレス
- サブルーチン呼び出しの次のコマンドのアドレス
- サブルーチンの処理から呼び出し側に戻るために必要
- サブルーチンを実行する前にリターンアドレスをスタックに格納
- サブルーチン内部のreturnコマンドを読み込んだ場合リターンアドレスをスタックから取得してjump先を指定する
ブートストラップコード
- ROM[0]から始まるコードセグメント
- プログラムの最初に実行されるコード
- VMはSys.initを最初に呼び出し、Sys.initがメイン関数を呼び出す
- 各言語のコンパイラはSys.initから呼び出す関数を設定することで最初に実行されるコードを実現している
- Javaで最初にmain()メソッドが呼び出されるような制御がSys.initによって実現できる
実装
サブルーチン呼び出しコマンドとプログラムフロー制御コマンドに対応したVM変換器を実装する。 Kotlinで実装した例は以下。
感想
次章はこちら