天天看點

模拟器開發實踐--解釋vs編譯

指令碼的執行方式,大緻有兩種:解釋和編譯。兩者都是以二進制目标機器碼為輸入,所采取的執行政策不同。

何為解釋?就是說将機器碼逐條讀出,每讀一條就進行解碼、執行。實作相對簡單,一般用進階語言編寫解釋器,移植性好。能夠實作精确控制,友善中斷、異常處理,且能實作目标硬體功能的完全模拟。缺點是效率低下。

編譯,就是把二進制機器碼按塊進行轉換,生成本地機器能夠直接運作的指令碼,并存放入緩沖區。它能夠實作代碼的高效運作,前提是緩沖區的代碼會被反複調用。

通常情況下解釋執行的速度慢于編譯執行。原因是解釋執行時,不管以前有沒有執行過,都要對目前的指令進行分析譯碼,而編譯執行能夠記住過去執行過代碼,當再次調用時直接從緩沖區中取出編譯好的代碼直接執行。舉個例子,比如一段循環代碼:sub這行它會執行100次,編譯執行時隻在第1次執行時運作編譯器,然後的99次均直接執行緩沖區中的本機代碼;解釋執行要有100次調用解釋器的開銷。

模拟器開發實踐--解釋vs編譯

mov r0, # 100

模拟器開發實踐--解釋vs編譯

loop :

模拟器開發實踐--解釋vs編譯

sub  r0, r0, # 1

模拟器開發實踐--解釋vs編譯

bne  loop

模拟器開發實踐--解釋vs編譯

一般編譯執行的流程如下:

模拟器開發實踐--解釋vs編譯

for (;;)

模拟器開發實踐--解釋vs編譯
模拟器開發實踐--解釋vs編譯

     ... {

模拟器開發實踐--解釋vs編譯

    pc=目前塊入口位址();

模拟器開發實踐--解釋vs編譯

    if(pc被緩沖)

模拟器開發實踐--解釋vs編譯
模拟器開發實踐--解釋vs編譯

        ...{

模拟器開發實踐--解釋vs編譯

        fp=擷取緩沖區入口位址(pc);

模拟器開發實踐--解釋vs編譯

        fp();// 執行緩沖區中的代碼 

模拟器開發實踐--解釋vs編譯

        }

模拟器開發實踐--解釋vs編譯

    else

模拟器開發實踐--解釋vs編譯
模拟器開發實踐--解釋vs編譯

        ...{

模拟器開發實踐--解釋vs編譯

        生成代碼(pc);

模拟器開發實踐--解釋vs編譯

        }

模拟器開發實踐--解釋vs編譯

    }

編譯器編寫時要考慮的問題主要有:基本塊的劃分,中斷/異常模拟的實作,本機機器指令相關(如寄存器配置設定,指令編碼等)。

有張圖,展示了Mac上某x86模拟器動态編譯執行的架構:

模拟器開發實踐--解釋vs編譯