[ 目次, 前節, 次節, 索引 ]

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で設計した計算機をテストせよ.



[ 目次, 前節, 次節, 索引 ]