[ 目次, 前節,
次節, 索引 ]
5.2 レジスタ計算機シミュレータ
レジスタ計算機の設計をよく理解するには, 設計した計算機をテストし, 期待通りに働くか見る必要がある. 設計をテストする一つの方法は, 問題5.5のように, 制御器の演算を机上シミュレートすることである. しかしこれは単純至極の計算機以外では, 殆んど極めて退屈である. 本節では, レジスタ計算機言語で記述した計算機用のシミュレータを構成する. シミュレータは四つのインターフェース手続きを持つSchemeプログラムである. 第一はレジスタ計算機の記述を使い, 計算機モデル(その部分がシミュレートする計算機の部分に対応するデータ構造)を構成し, 他の三つはわれわれにモデルを操作し, 計算機をシミュレートさせる:
(make-machine 〈register-names〉 〈operations〉 〈controller〉)
は, 与えられたレジスタ, 演算および制御器を持つ計算機のモデルを構成し,
それを返す.
(set-register-contents! 〈machine-model〉 〈register-name〉 〈value〉)
は, 与えられた計算機のシミュレートされるレジスタに値を格納する.
(get-register-contents 〈machine-model〉 〈register-name〉)
は, 与えられた計算機のシミュレートされるレジスタの内容を返す.
(start 〈machine-model〉)
は, 与えられた計算機の実行をシミュレートする. 制御列の先頭から実行開始し,
その列の最後に達した時に停止する.
これらの手続きの使い方の例として, 5.1.1節のGCD計算機のモデルである
gcd-machineを次のように定義する.
(define gcd-machine
(make-machine
'(a b t)
(list (list 'rem remainder) (list '= =))
'(test-b
(test (op =) (reg b) (const 0))
(branch (label gcd-done))
(assign t (op rem) (reg a) (reg b))
(assign a (reg b))
(assign b (reg t))
(goto (label test-b))
gcd-done)))
make-machineの第一引数は, レジスタ名のリストである. 次の引数は,
表(二要素リストのリスト)で, 演算名と, 演算を実装する(つまり与えられた同じ入力値に対して同じ出力値を出す)Scheme手続きを対にする. 最後の引数は,
5.1節のようにラベルと計算機命令のリストとして制御器を規定する.
この計算機でGCDを計算するには, 入力レジスタを設定し, 計算機を実行開始し, シミュレーションが終了した時に結果を調べる:
(set-register-contents! gcd-machine 'a 206)
done
(set-register-contents! gcd-machine 'b 40)
done
(start gcd-machine)
done
(get-register-contents gcd-machine 'a)
2
この計算は, assignのような低レベルの計算機命令を遥かに複雑な演算でシミュレートするので, Schemeで書いたgcd手続きより遥かに遅く走る.
問題 5.7
このシミュレータを使い, 問題5.4で設計した計算機をテストせよ.
[ 目次, 前節, 次節, 索引 ]