从本篇开始,我将开辟一个原创系列来介绍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就设计完成啦!