從本篇開始,我將開辟一個原創系列來介紹JIT動態編譯器的原理以及用一個小例子來闡述實現方法。例子實現主要在WINDOWS平台下,基於VC,主要需要讀者了解函數指針的使用,以及一些簡單的匯編知識。在此希望各路高手觀賞和指正!
JIT動態編譯器主要用來實現虛擬機,方式是CPU指令轉譯。由於CPU是計算機的核心,為了簡單起見,設計一個簡單的8位CPU,並實現一個虛擬機來轉譯到PC平台。CPU被設計成8位是因為可以避免大端和小端問題,使得目的更加明確。
由於這個CPU是虛擬的,這樣就不要求關心流水線什么的,只需要關注CPU寄存器和CPU指令集就足夠了。為了簡單起見,不定義通用寄存器,只定義PC寄存器(指令地址寄存器)和比較寄存器,讀寫操作均直接在內存中完成。
這樣,用代碼表示為:
typedef struct { int R_PC; //PC寄存器 int R_CMP; //比較寄存器 }REG; extern REG CPUREG;
接下來就是定義匯編指令集對應的機器碼了,用代碼表示為:
#define I_NOP 0x00 //空指令 #define I_MOV 0x01 //數據傳輸指令 #define I_ADD 0x02 //加法指令 #define I_CMP 0x03 //比較指令 #define I_JMP 0x04 //無條件條轉指令 #define I_JCP 0x05 //比較跳轉指令
在這里只定義了空指令,數據傳輸指令,加法指令,比較指令,無條件跳轉指令,比較跳轉指令,這樣寫一個簡單的小程序也就足夠了。其中匯編語法定義為:
I_MOV op0 op1 把op1地址內容送至op0地址
I_ADD op0 op1 把op0地址內容和op1地址內容相加,結果送至op0地址
I_CMP op0 op1 比較op0和op1的地址內容,如果小於那么寄存器R_CMP置0,否則寄存器R_CMP置1
I_JMP op0 直接跳轉到op0這個地址,影響寄存器R_PC
I_JCP op0 op1 如果寄存器R_CMP為0,跳轉到op0;如果寄存器R_CMP為1,跳轉到op1
以上,一個極簡單的CPU就設計完成啦!