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中設計的機器。