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

📄 simulator.cpp

📁 一个可以模拟MIPS汇编语言在硬件上运行的模拟器。 该模拟器对于43条最常用的指令进行了实现。而且实现了端口通信
💻 CPP
📖 第 1 页 / 共 4 页
字号:
	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.T  = ((reg.regh[index1] ^ reg.regh[index2]) == 0) ? 0 : 1;
		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;
	}
}

//MFIH MTIH
word asm_30(word code)
{
	offset = (code & 0xFF);
	code = (code >> 8);
	index1 = (code & 7);
	switch (offset)
	{
	case 0: //MFIH
		reg.regh[index1] = reg.IH;
		return 0;
	case 1: //MTIH
		printf("\nMTIH : %04x ", reg.regh[index1]);
		reg.IH = reg.regh[index1];
		return 0;
	default:
		return E_UNKNOW;
	}
}

word asm_31(word code)
{
	index1 = (code & 0xF);
	code = (code >> 4);
	index2 = (code & 0x7F);
	if (index2 != 0)
		return E_UNKNOW;
	return asm_func_int(index1);
}

//*****************************************************************************
//模拟

struct TASM
{
	char *name;
	int code;
	int x,y,z;
};

int asm_total;
const struct TASM const_asm[] = {
	{"ADDSP3",1793,63743,65280,65535},
	{"B",4096,63488,65535,65535},
	{"BEQZ",9984,63743,65280,65535},
	{"BNEZ",12032,63743,65280,65535},
	{"SLL",14308,63743,65311,65507},
	{"SRL",14310,63743,65311,65507},
	{"SRA",14311,63743,65311,65507},
	{"ADDIU3",18400,63743,65311,65520},
	{"ADDIU",20224,63743,65280,65535},
	{"SLTI",22272,63743,65280,65535},
	{"SLTUI",24321,63743,65280,65535},
	{"BTEQZ",24576,65280,65535,65535},
	{"BTNEZ",24832,65280,65535,65535},
	{"SW-RS",25089,65280,65535,65535},
	{"ADDSP",25344,65280,65535,65535},
	{"MTSP",25824,65311,65535,65535},
	{"MOVE",26599,65311,65528,65535},
	{"LI",28417,63743,65280,65535},
	{"CMPI",30465,63743,65280,65535},
	{"LW-SP",38657,63743,65280,65535},
	{"LW",40929,63743,65311,65504},
	{"SW-SP",55041,63743,65280,65535},
	{"SW",57313,63743,65311,65504},
	{"ADDU",59389,63743,65311,65507},
	{"SUBU",59391,63743,65311,65507},
	{"JR",61184,63743,65535,65535},
	{"MFHI",61200,63743,65535,65535},
	{"MFLO",61202,63743,65535,65535},
	{"MFPC",61248,63743,65535,65535},
	{"SLT",61410,63743,65311,65535},
	{"SLTU",61411,63743,65311,65535},
	{"SLLV",61412,63743,65311,65535},
	{"SRLV",61414,63743,65311,65535},
	{"SRAV",61415,63743,65311,65535},
	{"CMP",61418,63743,65311,65535},
	{"NEG",61419,63743,65311,65535},
	{"AND",61420,63743,65311,65535},
	{"OR",61421,63743,65311,65535},
	{"XOR",61422,63743,65311,65535},
	{"NOT",61423,63743,65311,65535},
	{"MULT",61432,63743,65311,65535},
	{"MULTU",61433,63743,65311,65535},
	{"DIV",61434,63743,65311,65535},
	{"DIVU",61435,63743,65311,65535},
	{"NOP",2048,65535,65535,65535,},
	{"INT",63489,65520,65535,65535},
	{"MFIH",63232,63743,65535,65535},
	{"MTIH",63233,63743,65535,65535}
};

void init()
{
	asm_total = (int)(sizeof(const_asm)/sizeof(struct TASM));
	memset(asm_set,0,sizeof(func)*32);
	asm_set[0] = asm_00;
	asm_set[1] = asm_01;
	asm_set[2] = asm_02;
//	asm_set[3] = asm_03;
	asm_set[4] = asm_04;
	asm_set[5] = asm_05;
	asm_set[6] = asm_06;
//	asm_set[7] = asm_07;
	asm_set[8] = asm_08;
	asm_set[9] = asm_09;
	asm_set[10] = asm_10;
	asm_set[11] = asm_11;
	asm_set[12] = asm_12;
	asm_set[13] = asm_13;
	asm_set[14] = asm_14;
//	asm_set[15] = asm_15;
//	asm_set[16] = asm_16;
//	asm_set[17] = asm_17;
	asm_set[18] = asm_18;
	asm_set[19] = asm_19;
//	asm_set[20] = asm_20;
//	asm_set[21] = asm_21;
//	asm_set[22] = asm_22;
//	asm_set[23] = asm_23;
//	asm_set[24] = asm_24;
//	asm_set[25] = asm_25;
	asm_set[26] = asm_26;
	asm_set[27] = asm_27;
	asm_set[28] = asm_28;
	asm_set[29] = asm_29;
	asm_set[30] = asm_30;
	asm_set[31] = asm_31;
}

struct BreakStack
{
	int btotal;
	int bsize;
	word *list;
	BreakStack()
	{
		btotal = 0;
		bsize = 4;
		list = (word *)malloc(sizeof(word)*bsize);
	}
	word binsert(word addr)
	{
		word tmp;
		if ((tmp = mem.can_vst(addr)) != 0) return tmp;
		for (int i=0;i<btotal;i++)
		{
			if (list[i] == addr)
				return 0;
		}
		list[btotal++] = addr;
		if (btotal == bsize)
		{
			bsize <<= 1;
			word *temp = (word *)malloc(sizeof(word)*bsize);
			for (int i=0;i<btotal;i++)
				temp[i] = list[i];
			free(list);
			list = temp;
		}
		for (int i=0;i<btotal-1;i++)
		{
			int min = i;
			for (int j=i+1;j<btotal;j++)
			{
				if (list[j] < list[min])
					min = j;
			}
			if (min == i)
				continue;
			word tmp = list[i];
			list[i] = list[min];
			list[min] = tmp;
		}
		return 0;
	}
	void delbp(int index)
	{
		if (index >= 0 && index < btotal)
		{
			for (int i=index+1;i<btotal;i++)
				list[i-1] = list[i];
			btotal --;
		}
	}
	int is_break(word addr)
	{
		for (int i=0;i<btotal;i++)
		{
			if (list[i] < addr)
				continue;
			if (list[i] == addr)
				return 1;
			if (list[i] > addr)
				return 0;
		}
		return 0;
	}
	void list_break()
	{
		printf("\n   > BreakPoints: total = %d\n",btotal);
		for (int i=0;i<btotal;i++)
			printf("      %d\t%04x\n",i,list[i]);
	}
};


struct BreakStack breakstack;

struct AsmID
{
	char *name;
	int id;
};

struct AsmID IDList[] = {
	{"ADDSP3",0},
	{"B",2},
	{"BEQZ",4},
	{"BNEZ",5},
	{"SLL",6},
	{"SRL",6},
	{"SRA",6},
	{"ADDIU3",8},
	{"ADDIU",9},
	{"SLTI",10},
	{"SLTUI",11},
	{"BTEQZ",12},
	{"BTNEZ",12},
	{"SW-RS",12},
	{"ADDSP",12},
	{"MOVE",12},
	{"MTSP",12},
	{"LI",13},
	{"CMPI",14},
	{"LW-SP",18},
	{"LW",19},
	{"SW-SP",26},
	{"SW",27},
	{"ADDU",28},
	{"SUBU",28},
	{"JR",29},
	{"MFHI",29},
	{"MFLO",29},
	{"JALR",29},
	{"SLT",29},
	{"SLTU",29},
	{"SLLV",29},
	{"SRLV",29},
	{"SRAV",29},
	{"CMP",29},
	{"NEG",29},
	{"AND",29},
	{"OR",29},
	{"XOR",29},
	{"NOT",29},
	{"MULT",29},
	{"MULTU",29},
	{"DIV",29},
	{"DIVU",29},
	{"MFPC",29}
};

AsmID RegsList[] = {
	{"R0",0},
	{"R1",1},
	{"R2",2},
	{"R3",3},
	{"R4",4},
	{"R5",5},
	{"R6",6},
	{"R7",7}
};

//执行一条指令
//FILE* PCout = fopen("PC.log", "w");
word pc_step(int next = 0)
{
	PC = reg.PC;
//	fprintf(PCout, "%04x\n", PC);
//	fflush(PCout);
	if ((t = mem.can_vst(PC)) != 0) return t;
	IR = mem.read_mem(PC);
	if (next == 0 && breakstack.is_break(PC) != 0)
		return C_SBREAK;
	index1 = ((IR >> 11)& 0x001F);
	if (asm_set[index1] == NULL)
		return E_NOFUNC;
	else 
	{
		reg.PC++;
		return asm_set[index1](IR);
	}
}

int get_regs_id(char argv[])
{
	if (strlen(argv) != 2)
		return -1;
	for (int i=0;i<8;i++)
	{
		if (strcmp(argv,RegsList[i].name) == 0)
			return RegsList[i].id;
	}
	printf("%s",argv);
	return -1;
}

int get_number_10(char argv[],int lenlimit)
{
	int value = 0, len = strlen(argv);
	char ch;
	for (int i=0;i<len;i++)
	{
		ch = argv[i];
		value *= 10;
		if (ch >= '0' && ch <= '9')
			value |= (ch-'0') & 0xF;
		else return -1;
	}
	if (value >> lenlimit != 0)
		return -1;
	return value;
}

int get_number(char argv[],int lenlimit,int bin_mode = 0)
{
	int value = 0, len = strlen(argv);
	char ch;
	for (int i=0;i<len;i++)
	{
		ch = argv[i];
		value <<= 4;
		if (ch >= '0' && ch <= '9')
			value |= (ch-'0') & 0xF;
		else if (ch >= 'A' && ch <= 'F')
			value |= (ch-'A'+10) & 0xF;
		else if (ch >= 'a' && ch <= 'f')
			value |= (ch-'a'+10) & 0xF;
		else return -1;
	}
	if (bin_mode == 0)
	{
		if (value >> lenlimit != 0)
			return -1;
	}
	else
	{
		if ((value & (~lenlimit)) != 0)
			return -1;
	}
	return value;
}

void pc_decode(word code)
{
	const struct TASM *p = const_asm;
	int i;
	word j ,k;
	for (i=0;i<asm_total;i++)
	{
		j = ((*p).code & (*p).x & (*p).y & (*p).z); 
		k = (code & (*p).x & (*p).y & (*p).z);
		if (j == k)
			break;
		p ++;
	}
	printf("  <%04x>",code);
	if (i == asm_total)
	{
		printf("--- UNKNOWN ---");
		return ;
	}
	printf(" %s",(*p).name);
	word regs[3];
	word num;
	regs[0] = ~(*p).x;
	regs[1] = ~(*p).y;
	regs[2] = ~(*p).z;
	for (i=0;i<3;i++)
	{
		if (regs[i] != 0)
		{
			k = (regs[i] & (*p).code);
			num = (regs[i] & code);
			if (regs[i] == k)
			{
				while ((regs[i] & 1) == 0)
				{
					num = (num >> 1);
					regs[i] = (regs[i] >> 1);
				}
				printf(" R%d",num);
			}
			else if (k == 0)
			{
				while ((regs[i] & 1) == 0)
				{
					num = (num >> 1);
					regs[i] = (regs[i] >> 1);
				}
				j = ~regs[i];
				if ((num & (j >> 1)) != 0)
					num = (num | j);
				printf(" %04x",num);
			}
			else
			{
				while ((regs[i] & 1) == 0)
				{
					num = (num >> 1);
					regs[i] = (regs[i] >> 1);
				}
				printf(" %04x",num);
			}
		}
	}
}

void run_regs(int ,char *[]);

void run_continue(int argc,char *argv[])
{
	if (argc == 2)
	{
		if (strcmp(argv[1],"int") != 0)
		{
			printf ("\n Unknown control identifier `%s'.\n", argv [1]);
			return ;
		}
	}
	else if (argc != 1)
	{
		printf ("\n Unknown control identifier ");
		for (int i=1;i<argc;i++)
			printf("`%s' ", argv [i]);
		printf("\n");
		return ;
	}
	printf("\n");
	word err;
	char ch;
	int step = 0;
	console_mode = 0;
	if (argc == 2)
		int_mode = 1;
	int int_count = 0;
	while ((err = pc_step()) == 0)
	{
		if (step == 0x100)
		{
			if (kbhit())
			{
				while (kbhit())
				{
					ch = getch();
					if (ch == 7)
					{
						run_regs(1,argv);
						console_mode = -1;
						return ;
					}
					else if (ch == 21)
						asm_func_int(0x10);
				}
			}
			step = 0;
		}
		step ++;
		if (int_mode == 1)
		{
			if ((reg.IH & 0x8000) == 0)
				int_count = 0;
			else
				int_count ++;
			if (int_count == const_int_step)
			{
				int_count = 0;
				asm_func_int(0x20);
			}
		}
	}
	switch (err)
	{
	case C_SBREAK:
		printf("\n    [%04x] %04x   ",PC,IR);
		pc_decode(IR);
		break;
	case E_NOFUNC:
		printf("\n    no such function\n");
		break ;
	case E_MMNVST:
		printf("\n    Can not read memory :  [%04x]  ",PC);
		pc_decode(IR);
		break ;
	default: printf("\n    error %d\n",err);
		break;
	}
	console_mode = -1;
	int_mode = 0;
}

void run_step(int argc,char *argv[])
{
	word err;
	console_mode = 0;
	if (argc == 1)
	{
		err = pc_step(1);
		PC = reg.PC;
		if (mem.can_vst(PC) != 0 || err != 0)
			printf("    Cannot read memory\n");
		else
		{
			IR = mem.read_mem(PC);
			printf("\n   [%04x]  %04x  ",PC,IR);
			pc_decode(IR);
		}
	}
	else
	{
		int value = get_number(argv[1],16);
		if (value == -1)
		{
			printf ("\n Unknown control identifier `%s'.\n", argv [1]);
			console_mode = -1;
			return ;
		}
		for (int i=0;i<value;i++)
		{
			err = pc_step(1);
			if (err != 0)
			{
				PC = reg.PC;
				if (mem.can_vst(PC) != 0)
				printf("\n    Cannot read memory\n");
				else
				{
					IR = mem.read_mem(PC);
					printf("\n   [%04x]  %04x  ",PC,IR);
					pc_decode(IR);
				}
				break;
			}
		}
		run_regs(1,argv);
	}
	console_mode = -1;
}

void run_quit(int argc,char *argv[])
{
	if (argc != 1)
	{
		printf ("\n Unknown control identifier `%s'.\n", argv [1]);
		return ;

⌨️ 快捷键说明

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