1. 程式人生 > >5.2 一個暫存器機器的模擬器

5.2 一個暫存器機器的模擬器

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>)
模擬給定機器的執行,從控制器的執行序列的開頭開始,當到達序列的結尾時停止。

作為這些程式如何被使用的一個例子,我們能夠定義 gcd-machine 作為5.1.1
部分的GCD機器的一個模型,如下所示:

(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

這個計算將比一個在scheme寫成的GCD的程式執行得更慢。
因為我們將用更多的複雜的操作來模擬底層的機器指令,例如賦值指令。

練習5。7
使用模擬器來測試你在練習5。4中設計的機器。