⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 simulator.cpp

📁 一个用C++实现的C的Compiler。 代码风格良好。 原作者自己写了这个编译器
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <windows.h>
#include <conio.h>
#include <cstring>


typedef	unsigned short word;
typedef unsigned short regis;
typedef word (*func) (word);
typedef void (*decode) (word);

const int LimitConsoleBuffer = 4096;

const word E_NOFILE = 1;
const word W_MMEXST = 2;
const word W_MMDRTY = 3;
const word E_UNKNOW = 4;
const word E_MMREAD = 5;
const word E_MMWRTE = 6;
const word E_MMNVST = 7;
const word E_NOFUNC = 8;
const word C_SBREAK = 9;
const word E_DIVZER = 10;
const int SCRN_X = 80;
const int SCRN_Y = 100;
void stop();

//*****************************************************************************
//寄存器堆
struct RegHeap
{
	regis T:1;
	regis regh[8];
	regis PC;
	regis RA;
	regis SP;
	regis HI;
	regis LO;
	RegHeap();
	void list_regs();
};

RegHeap::RegHeap()
{
	T = 0;
	PC = 0x0001;
	SP = 0xDFFF;
}

void RegHeap::list_regs()
{
	for (int i=0;i<8;i++)
	{
		printf("    R%d = %04x",i,regh[i]);
		if ((i+1) % 4 == 0)
			printf("\n");
	}
	printf("    PC = %04x    RA = %04x    SP = %04x     T = %04x\n",PC,RA,SP,T);
	printf("    HI = %04x    LO = %04x\n",HI,LO);
}

struct RegHeap reg;
//*****************************************************************************
//内存
struct Memory
{
	word flags0, flags1;
	static const word MEM_SIZE = 0xE000;
	Memory();
	word can_vst(word index);
	word load_mem(char *rom_file);
	word read_mem(word );
	void save_mem(char *rom_file);
	void write_mem(word ,word );
	word memory[MEM_SIZE];
};

Memory::Memory()
{
	flags0 = 0;
	flags1 = 0;
	memset(memory,0,sizeof(word)*MEM_SIZE);
};

word Memory::load_mem(char *rom_file)
{
	FILE *rom_handle = fopen(rom_file,"rb");
	if (rom_handle == NULL)
		return E_NOFILE;
	fread(memory,sizeof(word),MEM_SIZE,rom_handle);
	fclose(rom_handle);
	return 0;
}

void Memory::save_mem(char *rom_file)
{
	FILE *rom_handle = fopen(rom_file,"wb+");
	fwrite(memory,sizeof(word),MEM_SIZE,rom_handle);
}

word Memory::can_vst(word index)
{
	return ((index < MEM_SIZE) ? 0 : E_MMNVST);
}

word Memory::read_mem(word index)
{
	if (index == 0x8000)
	{
		memory[index] = (word)getch();
	}
	return memory[index];
}

void Memory::write_mem(word index,word str)
{
	memory[index] = str;
	if (index == 0x8000)
	{
//		printf("(%d)", str);
		printf("%c",str);
	}
}

struct Memory mem;
//*****************************************************************************
//定义全部汇编指令
word index1, index2 ,index3, offset, F , t;

//ADDIU_SP_3OP
word asm_00(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	reg.regh[index1] = reg.SP+offset;
	return 0;
}

//B
word asm_02(word code)
{
	offset = (code & 0x7FF);
	if ((offset & 0x400) != 0)
		offset |= 0xF800;
	reg.PC += offset;
	return 0;
}

//BEQZ
word asm_04(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	if (reg.regh[index1] == 0)
		reg.PC += offset;
	return 0;
}

//BNEZ
word asm_05(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	if (reg.regh[index1] != 0)
		reg.PC += offset;
	return 0;
}

//SLL SRL SRA
word asm_06(word code)
{
	index3 = (code & 0x3);
	code >>= 2;
	offset = (code & 0x7);
	code >>= 3;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	switch (index3)
	{
	case 0: //SLL
		reg.regh[index1] = (offset == 0) ? (reg.regh[index2] << 8) : (reg.regh[index2] << offset);
		return 0;
	case 2: //SRL
		reg.regh[index1] = (offset == 0) ? (reg.regh[index2] >> 8) : (reg.regh[index2] >> offset);
		return 0;
	case 3: //SRA
		reg.regh[index1] = (offset == 0) ? (((short )reg.regh[index2]) >> 8) : (((short )reg.regh[index2]) >> offset);
		return 0;
	default: return E_UNKNOW;
	}
}

//ADDIU_3OP
word asm_08(word code)
{
	offset = (code & 0xF);
	code >>= 4;
	index3 = (code & 0x1);
	code >>= 1;
	if (index3 != 0) 
		return E_UNKNOW;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	if ((offset & 0x8) != 0)
		offset |= 0xFFF0;
	reg.regh[index2] = reg.regh[index1]+offset;
	return 0;
}

//ADDIU
word asm_09(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0 )
		offset |= 0xFF00;
	reg.regh[index1] += offset;
	return 0;
}

//SLTI
word asm_10(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	reg.T = ((short)reg.regh[index1] < (short)offset) ? 1 : 0;
	return 0;
}

//SLTUI
word asm_11(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	reg.T = (reg.regh[index1] < offset) ? 1 : 0;
	return 0;
}

//BTEQZ BTNEZ SW-RA-SP ADDIU_SP MOVE
word asm_12(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index3 = (code & 0x7);
	switch (index3)
	{
	case 0: //BTEQZ
		if (reg.T == 0)
		{
			if ((offset & 0x80) != 0)
				offset |= 0xFF00;
			reg.PC += offset;
		}
		return 0;
	case 1: //BTNEZ
		if (reg.T != 0)
		{
			if ((offset & 0x80) != 0)
				offset |= 0xFF00;
			reg.PC += offset;
		}
		return 0;
	case 2: //SW-RA-SP
		F = reg.SP+offset;
		if ((t = mem.can_vst(F)) != 0) return t;
		mem.write_mem(F,reg.RA);
		return 0;
	case 3: // ADDIU_SP
		if ((offset & 0x80) != 0)
			offset |= 0xFF00;
		reg.SP += offset;
		return 0;
	case 7: //MOVE
		index2 = (offset & 0x7);
		offset >>= 3;
		if ((offset & 0x3) != 0)
			return E_UNKNOW;
		offset >>= 2;
		index1 = (offset & 0x7);
		reg.regh[index1] = reg.regh[index2];
		return 0;
	default: return E_UNKNOW;
	}
}

//LI
word asm_13(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	reg.regh[index1] = offset;
	return 0;
}

//CMPI
word asm_14(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	reg.regh[index1] ^= offset;
	return 0;
}

//LW-SP
word asm_18(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	F = reg.SP+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	reg.regh[index1] = mem.read_mem(F);
	return 0;
}

//LW
word asm_19(word code)
{
	offset = (code & 0x1F);
	code >>= 5;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	F = reg.regh[index1]+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	reg.regh[index2] = mem.read_mem(F);
	return 0;
}

//SW-SP
word asm_26(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	F = reg.SP+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	mem.write_mem(F,reg.regh[index1]);
	return 0;
}

//SW
word asm_27(word code)
{
	offset = (code & 0x1F);
	code >>= 5;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	F = reg.regh[index1]+offset;
	if ((t = mem.can_vst(F)) != 0) return t;
	mem.write_mem(F,reg.regh[index2]);
	return 0;
}

//ADDU SUBU
word asm_28(word code)
{
	offset = (code & 0x3);
	code >>= 2;
	index3 = (code & 0x7);
	code >>= 3;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	switch (offset)
	{
	case 1: //ADDU
		reg.regh[index3] = reg.regh[index1]+reg.regh[index2];
		return 0;
	case 3: //SUBU
		reg.regh[index3] = reg.regh[index1]-reg.regh[index2];
		return 0;
	default: return E_UNKNOW;
	}
}

//JR(ra) JR MFHI MFLO JALR SLT SLTU SLLV SRLV SRAV CMP NEG AND OR XOR NOT MULT MULTU DIV DIVU
word asm_29(word code)
{
	index3 = (code & 0x1F);
	code >>= 5;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	if (index3 == 0)
	{
		switch (index2)
		{
		case 0: //JR(ra)
			reg.PC = reg.regh[index1];
			return 0;
		case 2: //MFPC
			reg.regh[index1] = reg.PC;
			return 0;
		case 1: //JR
			if (index1 != 0) return E_UNKNOW;
			reg.PC = reg.RA;
			return 0;
		case 6: //JALR
			reg.RA = reg.PC;
			reg.PC = reg.regh[index1];
			return 0;
		default: return E_UNKNOW;
		}
	}
	unsigned int mul;
	switch (index3)
	{
	case 2: //SLT
		reg.T = ((short)reg.regh[index1] < (short)reg.regh[index2]) ? 1 : 0;
		return 0;
	case 3: //SLTU
		reg.T = (reg.regh[index1] < reg.regh[index2]) ? 1 : 0;
		return 0;
	case 4: //SLLV
		reg.regh[index2] = (reg.regh[index2] << reg.regh[index1]);
		return 0;
	case 6: //SRLV
		reg.regh[index2] = (reg.regh[index2] >> reg.regh[index1]);
		return 0;
	case 7: //SRAV
		reg.regh[index2] = (((short )reg.regh[index2]) >> reg.regh[index1]);
		return 0;
	case 10: //CMP
		reg.regh[index1] ^= reg.regh[index2];
		return 0;
	case 11: //NEG
		reg.regh[index1] = -reg.regh[index2];
		return 0;
	case 12: //AND
		reg.regh[index1] &= reg.regh[index2];
		return 0;
	case 13: //OR
		reg.regh[index1] |= reg.regh[index2];
		return 0;
	case 14: //XOR
		reg.regh[index1] ^= reg.regh[index2];
		return 0;
	case 15: //NOT
		reg.regh[index1] = ~reg.regh[index2];
		return 0;
	case 16: //MFHI
		reg.regh[index1] = reg.HI;
		return 0;
	case 18: //MFLO
		reg.regh[index1] = reg.LO;
		return 0;
	case 24: //MULT
		mul = (int)reg.regh[index1]*(int)reg.regh[index2];
		reg.HI = (word)((mul >> 16) & 0xFFFF);
		reg.LO = (word)(mul & 0xFFFF);
		return 0;
	case 25: //MULTU
		mul = (unsigned int)(reg.regh[index1])*(unsigned int)(reg.regh[index2]);
		reg.HI = (word)((mul >> 16) & 0xFFFF);
		reg.LO = (word)(mul & 0xFFFF);
		return 0;
	case 26: //DIV
		if (reg.regh[index2] == 0)
			return E_DIVZER;
		reg.LO = (word)((short)reg.regh[index1]/(short)reg.regh[index2]);
		reg.HI = (word)((short)reg.regh[index1]%(short)reg.regh[index2]);
		return 0;
	case 27: //DIVU
		if (reg.regh[index2] == 0)
			return E_DIVZER;
		reg.LO = reg.regh[index1]/reg.regh[index2];
		reg.HI = reg.regh[index1]%reg.regh[index2];
		return 0;
	default: return E_UNKNOW;
	}
}

//*****************************************************************************
//解码

void unknown_printf()
{
	printf("**********");
}

void unknown_decode(word code)
{
	printf("---unknown---  <%04x>",code);
}

//ADDIU_SP_3OP
void decode_00(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	printf("ADDSP R%x %04x",index1,offset);
}

//B
void decode_02(word code)
{
	offset = (code & 0x7FF);
	if ((offset & 0x400) != 0)
		offset |= 0xF800;
	printf("B      %04x",offset);
}

//BEQZ
void decode_04(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	printf("BEQZ  R%x %04x",index1,offset);
}

//BNEZ
void decode_05(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	printf("BNEZ  R%x %04x",index1,offset);
}

//SLL SRL SRA
void decode_06(word code)
{
	index3 = (code & 0x3);
	code >>= 2;
	offset = (code & 0x7);
	code >>= 3;
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	switch (index3)
	{
	case 0: printf("SLL  "); break;
	case 2: printf("SRL  "); break;
	case 3: printf("SRA  "); break;
	default: 
		unknown_printf();
		return ;
	}
	printf(" R%x R%x %04x",index1,index2,offset);
}

//ADDIU_3OP
void decode_08(word code)
{
	offset = (code & 0xF);
	code >>= 4;
	index3 = (code & 0x1);
	code >>= 1;
	if (index3 != 0) 
	{
		unknown_printf();
		return ;
	}
	index2 = (code & 0x7);
	code >>= 3;
	index1 = (code & 0x7);
	if ((offset & 0x8) != 0)
		offset |= 0xFFF0;
	printf("ADDIU R%x R%x %04x",index1,index2,offset);
}

//ADDIU
void decode_09(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0 )
		offset |= 0xFF00;
	printf("ADDIU R%x %04x",index1,offset);
}

//SLTI
void decode_10(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	if ((offset & 0x80) != 0)
		offset |= 0xFF00;
	printf("SLTI  R%x %04x",index1,offset);
}

//SLTUI
void decode_11(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index1 = (code & 0x7);
	printf("SLTUI R%x %04x",index1,offset);
}

//BTEQZ BTNEZ SW-RA-SP ADDIU_SP MOVE
void decode_12(word code)
{
	offset = (code & 0xFF);
	code >>= 8;
	index3 = (code & 0x7);
	switch (index3)
	{
	case 0: //BTEQZ
		if ((offset & 0x80) != 0)
			offset |= 0xFF00;
		printf("BTEQZ"); 

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -