JIT动态编译器的原理与实现之实现自己CPU的程序(二)


    在上篇设计了一个极简单的CPU,并定义了相应的寄存器和指令集。接下来就是利用定义的寄存器和指令集完成一个程序,最后实现一个虚拟机来运行这个程序。


    这个程序由汇编语言编写,并且手工编译成机器码。为了简单起见,设定CPU的寻址范围为64字节。程序代码为:

CODE:
04 12     I_JMP 12        //直接跳转到内存12的地址
DATA:
00 00 01 00 07 0F 08 07 00 00 00 00 00 00 00 00 //03-11为数据区
CODE:
02 03 04 I_ADD 03 04 //将03和04地址内容相加,结果送入03地址
02 05 06 I_ADD 05 06 //将05和06地址内容相加,结果送入05地址
03 03 07 I_CMP 03 07 //比较03和07地址内容
05 1E 20 I_JCP  1E 20 //根据寄存器R_CMP的值决定跳转到1E或20地址
04 23      I_JMP  23     //直接跳转到23地址
01 03 02 I_MOV 03 02 //把02地址内容送至03地址
03 05 07 I_CMP 05 07 //比较05和07地址内容
05 29 2B I_JCP  29 2B //根据寄存器R_CMP的值决定跳转到29或2B地址
04 2E      I_JMP  2E    //直接跳转到2E地址
01 05 02 I_MOV 05 02 //把02地址内容送至05地址
04 12     I_JMP    12    //直接跳转到内存12的地址

    接着用任意16进制编辑器将机器码和数据输入,然后另存为一个文件,这里另存为rom.bin。如下图:

 

    最后,需要将程序载入内存,为虚拟机运行程序做准备,对应代码为:

#define MEMSIZE 64

unsigned char* RAM;

int loadROM(void);

int memInit(void);
void memFree(void);

int loadROM(void)
{
	FILE* rom;

	if ((rom = fopen("rom.bin", "r")) == NULL)
	{
		
		MessageBox(NULL, "Cannot find rom file", "Warning", MB_OK);

		return 1;
	}
   
	fread((void*)RAM, sizeof(char), MEMSIZE, rom);
	fclose(rom);


	return 0;
}

int memInit(void)
{
	

	RAM = (unsigned char*)GlobalAlloc(GMEM_FIXED,MEMSIZE);      
	

	if (RAM == NULL)
	{
		
		MessageBox(NULL, "Cannot allocate enough memory", "Error", MB_OK);

		return 1;
	}

	return 0;
}

void memFree(void)
{

	GlobalFree(RAM);
	
}

 
    当然,也可以用int数组来保存这段程序,但这里只是希望看起来更像是真正的外部程序。

原文地址:https://www.cnblogs.com/SSforME/p/2824128.html