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

📄 loader.cpp

📁 run mips program using C++
💻 CPP
字号:
#include "loader.h"using namespace std;Program::Program(){	instrNum = 0;	labelNum = 0;	flag = 1;		// flag should be 0 for full assembly language simulator	instrPos = 0;	/*code opcode and funct. initilization*/	/*add*/	OPSet[0].type = 0;	OPSet[0].code = 0;	OPSet[0].funct = 32;	strcpy(OPSet[0].name,"add");	/*sub*/	OPSet[1].type = 0;	OPSet[1].code = 0;	OPSet[1].funct = 34;	strcpy(OPSet[1].name,"sub");	/*addi*/	OPSet[2].type = 1;	OPSet[2].code = 8;	OPSet[2].funct = 0;	strcpy(OPSet[2].name,"addi");	/*and*/	OPSet[3].type = 0;	OPSet[3].code = 0;	OPSet[3].funct = 36;	strcpy(OPSet[3].name, "and");	/*andi*/	OPSet[4].type = 1;	OPSet[4].code = 12;	OPSet[4].funct = 0;	strcpy(OPSet[4].name, "andi");	/*or*/	OPSet[5].type = 0;	OPSet[5].code = 0;	OPSet[5].funct = 37;	strcpy(OPSet[5].name, "or");	/*ori*/	OPSet[6].type = 1;	OPSet[6].code = 13;	OPSet[6].funct = 0;	strcpy(OPSet[6].name, "ori");	/*sll*/	OPSet[7].type = 0;	OPSet[7].code = 0;	OPSet[7].funct = 0;	strcpy(OPSet[7].name, "sll");	/*slt*/	OPSet[8].type = 0;	OPSet[8].code = 0;	OPSet[8].funct = 42;	strcpy(OPSet[8].name, "slt");	/*lui*/	OPSet[9].type = 1;	OPSet[9].code = 15;	OPSet[9].funct = 0;	strcpy(OPSet[9].name, "lui");	/*bne*/	OPSet[10].type = 1;	OPSet[10].code = 5;	OPSet[10].funct = 0;	strcpy(OPSet[10].name, "bne");	/*j*/	OPSet[11].type = 2;	OPSet[11].code = 2;	OPSet[11].funct = 0;	strcpy(OPSet[11].name, "j");	/*jr*/	OPSet[12].type = 3;	OPSet[12].code = 0;	OPSet[12].funct = 8;	strcpy(OPSet[12].name, "jr");	/*lw*/	OPSet[13].type = 4;	OPSet[13].code = 35;	OPSet[13].funct = 0;	strcpy(OPSet[13].name, "lw");	/*sw*/	OPSet[14].type = 4;	OPSet[14].code = 43;	OPSet[14].funct = 0;	strcpy(OPSet[14].name, "sw");	/*beq*/	OPSet[15].type = 1;	OPSet[15].code = 4;	OPSet[15].funct = 0;	strcpy(OPSet[15].name, "beq");	/*srl*/	OPSet[16].type = 0;	OPSet[16].code = 0;	OPSet[16].funct = 2;	strcpy(OPSet[16].name, "srl");	/*Register initialization*/    /*zero*/	RegSet[0].used = 0;	RegSet[0].code = 0;	strcpy(RegSet[0].name, "$zero");	RegSet[0].value = 0;	/*at*/	RegSet[1].used = 0;	RegSet[1].code = 1;	strcpy(RegSet[1].name, "$at");	RegSet[1].value = 0;	/*v0*/	RegSet[2].used = 0;	RegSet[2].code = 2;	strcpy(RegSet[2].name, "$v0");	RegSet[2].value = 0;	/*v1*/	RegSet[3].used = 0;	RegSet[3].code = 3;	strcpy(RegSet[3].name, "$v1");	RegSet[3].value = 0;	/*a0*/	RegSet[4].used = 0;	RegSet[4].code = 4;	strcpy(RegSet[4].name, "$a0");	RegSet[4].value = 0;	/*a1*/	RegSet[5].used = 0;	RegSet[5].code = 5;	strcpy(RegSet[5].name, "$a3");	RegSet[5].value = 0;	/*a2*/	RegSet[6].used = 0;	RegSet[6].code = 6;	strcpy(RegSet[6].name, "$a2");	RegSet[6].value = 0;	/*a3*/	RegSet[7].used = 0;	RegSet[7].code = 7;	strcpy(RegSet[7].name, "$a3");	RegSet[7].value = 0;	/*t0*/	RegSet[8].used = 0;	RegSet[8].code = 8;	strcpy(RegSet[8].name, "$t0");	RegSet[8].value = 0;	/*t1*/	RegSet[9].used = 0;	RegSet[9].code = 9;	strcpy(RegSet[9].name, "$t1");	RegSet[9].value = 0;	/*t2*/	RegSet[10].used = 0;	RegSet[10].code = 10;	strcpy(RegSet[10].name, "$t2");	RegSet[10].value = 0;	/*t3*/	RegSet[11].used = 0;	RegSet[11].code = 11;	strcpy(RegSet[11].name, "$t3");	RegSet[11].value = 0;	/*t4*/	RegSet[12].used = 0;	RegSet[12].code = 12;	strcpy(RegSet[12].name, "$t4");	RegSet[12].value = 0;	/*t5*/	RegSet[13].used = 0;	RegSet[13].code = 13;	strcpy(RegSet[13].name, "$t5");	RegSet[13].value = 0;	/*t6*/	RegSet[14].used = 0;	RegSet[14].code = 14;	strcpy(RegSet[14].name, "$t6");	RegSet[14].value = 0;	/*t7*/	RegSet[15].used = 0;	RegSet[15].code = 15;	strcpy(RegSet[15].name, "$t7");	RegSet[15].value = 0;	/*s0*/	RegSet[16].used = 0;	RegSet[16].code = 16;	strcpy(RegSet[16].name, "$s0");	RegSet[16].value = 0;	/*s1*/	RegSet[17].used = 0;	RegSet[17].code = 17;	strcpy(RegSet[17].name, "$s1");	RegSet[17].value = 0;	/*s2*/	RegSet[18].used = 0;	RegSet[18].code = 18;	strcpy(RegSet[18].name, "$s2");	RegSet[18].value = 0;	/*s3*/	RegSet[19].used = 0;	RegSet[19].code = 19;	strcpy(RegSet[19].name, "$s3");	RegSet[19].value = 0;	/*s4*/	RegSet[20].used = 0;	RegSet[20].code = 20;	strcpy(RegSet[20].name, "$s4");	RegSet[20].value = 0;	/*s5*/	RegSet[21].used = 0;	RegSet[21].code = 21;	strcpy(RegSet[21].name, "$s5");	RegSet[21].value = 0;	/*s6*/	RegSet[22].used = 0;	RegSet[22].code = 22;	strcpy(RegSet[22].name, "$s6");	RegSet[22].value = 0;	/*s7*/	RegSet[23].used = 0;	RegSet[23].code = 23;	strcpy(RegSet[23].name, "$s7");	RegSet[23].value = 0;	/*t8*/	RegSet[24].used = 0;	RegSet[24].code = 24;	strcpy(RegSet[24].name, "$t8");	RegSet[24].value = 0;	/*t9*/	RegSet[25].used = 0;	RegSet[25].code = 25;	strcpy(RegSet[25].name, "$t9");	RegSet[25].value = 0;	/*k0*/	RegSet[26].used = 0;	RegSet[26].code = 26;	strcpy(RegSet[26].name, "$k0");	RegSet[26].value = 0;	/*k1*/	RegSet[27].used = 0;	RegSet[27].code = 27;	strcpy(RegSet[27].name, "$k1");	RegSet[27].value = 0;	/*gp*/	RegSet[28].used = 0;	RegSet[28].code = 28;	strcpy(RegSet[28].name, "$gp");	RegSet[28].value = 0;	/*sp*/	RegSet[29].used = 0;	RegSet[29].code = 29;	strcpy(RegSet[29].name, "$sp");	RegSet[29].value = 0;	/*fp*/	RegSet[30].used = 0;	RegSet[30].code = 30;	strcpy(RegSet[30].name, "$fp");	RegSet[30].value = 0;	/*ra*/	RegSet[31].used = 0;	RegSet[31].code = 31;	strcpy(RegSet[31].name, "$ra");	RegSet[31].value = 0;}Program::~Program(){}unsigned int Program::GetOPCode(const char *op){	for(int i=0;i<INSTR_TYPE;i++)	{		if(!strcmp(op,OPSet[i].name))			return OPSet[i].code;	}	assert(1);}unsigned int Program::GetFunct(const char *op){	for(int i=0;i<INSTR_TYPE;i++)	{		if(!strcmp(op,OPSet[i].name))			return OPSet[i].funct;	}	assert(1);}char* Program::GetRegName(const unsigned int reg){	for(int i=0;i<REGISTER_NUM;i++)	{		if(RegSet[i].code == reg)			return RegSet[i].name;	}	assert(1);}unsigned int Program::GetRegCode(const char *reg){	int i;	// it is a register	for(i=0;i<REGISTER_NUM;i++)	{		if(!strcmp(reg,RegSet[i].name))		{			RegSet[i].used = 1;			return RegSet[i].code;		}	}	// it is a label	for(i=0;i<MAX_LABEL_NUM;i++)	{		if(!strcmp(reg,labelTable[i].name))			return labelTable[i].offset;	}	// it is an immediate number	return (unsigned int)atoi(reg);}int Program::LoadProgram(const char *fileName){	ifstream file,fix;	char *line;	unsigned int instrBuff;	file.open(fileName,ios::in);	if(file.fail())	{		cout<<"The file \""<<fileName<<"\" does not exist!"<<endl;		return -2;	}	// load the program into the program[]	line = new char[MAX_LINE_LENGTH];	while( file.getline(line,MAX_LINE_LENGTH,'\n') )	{		strcpy(program[instrNum].instrName, line);		instrBuff = GenerateInstr(line);		if(instrBuff == (unsigned)-2)			continue;		if(instrBuff == (unsigned)-1)		{			cout<<"Instruction No. "<<instrNum+1<<" has format error!"<<endl;			return -1;		}		program[instrNum++].instrCode = instrBuff;	}	file.close();	// fix all labels that are used before its definition in the program	fix.open(fileName,ios::in);	flag = 0;	while( fix.getline(line,MAX_LINE_LENGTH,'\n') )		FixLabels(line);	fix.close();	return instrNum;}void Program::FixLabels(char *line){	int i, j;	char space[] = " \t";	char colon[] = ":";	char *label, *op, *buff;	op   = new char[KEY_LENGTH];	buff = new char[MAX_LINE_LENGTH];	strcpy(buff,line);	op   = strtok(line, space);	if(op != NULL)	{		for(i=0;i<INSTR_TYPE;i++)		{			if(!strcmp(op,OPSet[i].name))				break;		}		if(i != INSTR_TYPE)	// it is an instruction		{			instrPos++;			for(j=0;j<labelNum;j++)			{				label = strstr(buff, labelTable[j].name);				if(label != NULL && strstr(label, colon) == NULL)	// find a label				{					if(OPSet[i].type == 2)					{						program[flag].instrCode = ( (program[flag].instrCode >> 26) << 26 ) + labelTable[j].offset;						program[flag].instr.AD = labelTable[j].offset;					}					if(OPSet[i].type == 1)					{						if(strcmp(op,"beq")!=0)						{							program[flag].instrCode = ( (program[flag].instrCode >> 16) << 16 ) + labelTable[j].offset;							program[flag].instr.IM = labelTable[j].offset;						}						else						{							program[flag].instrCode = ( (program[flag].instrCode >> 16) << 16 ) + ((labelTable[j].offset-instrPos) << 16 >> 16);							program[flag].instr.IM = labelTable[j].offset-instrPos;						}					}				}			}			flag ++;		}	}}unsigned int Program::GenerateInstr(char *line){	int  i;	char space[] = " \t,";	char *op, *reg1, *reg2, *reg3;	unsigned int oneInstr, tmp;	op = new char[KEY_LENGTH];	reg1 = new char[KEY_LENGTH];	reg2 = new char[KEY_LENGTH];	reg3 = new char[KEY_LENGTH];	op = strtok(line, space);	if(op != NULL)	{		for(i=0;i<INSTR_TYPE;i++)		{			if(!strcmp(op,OPSet[i].name))				break;		}		if(i != INSTR_TYPE)	// it is an instruction		{			switch(OPSet[i].type)			{			// handle the R-format instructions			case 0:				tmp = GetOPCode(op);				oneInstr = tmp << 26;				program[instrNum].instr.OP = tmp;				tmp = GetFunct(op);				oneInstr += tmp;				program[instrNum].instr.FN = tmp;				program[instrNum].instr.SH = 0;				program[instrNum].instr.IM = (unsigned)-1;				program[instrNum].instr.AD = (unsigned)-1;				reg1 = strtok(NULL, space);	// get the first reg				if(reg1 != NULL)				{					tmp = GetRegCode(reg1);					program[instrNum].instr.RD = tmp;					oneInstr += tmp << 11;					reg2 = strtok(NULL, space);	// get the second operator					if(reg2 != NULL)					{						tmp = GetRegCode(reg2);						program[instrNum].instr.RS = tmp;						oneInstr += tmp << 21;						reg3 = new char[KEY_LENGTH];						reg3 = strtok(NULL, space);	// get the third operator						if(reg3 != NULL)						{							tmp = GetRegCode(reg3);							program[instrNum].instr.RT = tmp;							oneInstr += tmp << 16;							reg3 = strtok(NULL, space);	// error detection							if(reg3 != NULL)								return (unsigned)-1;						}					}				}				break;			// handle the I-format instructions			case 1:				tmp = GetOPCode(op);				oneInstr = tmp << 26;				program[instrNum].instr.OP = tmp;				program[instrNum].instr.FN = (unsigned)-1;				program[instrNum].instr.SH = (unsigned)-1;				program[instrNum].instr.IM = 0;				program[instrNum].instr.RD = (unsigned)-1;				program[instrNum].instr.AD = (unsigned)-1;				reg1 = strtok(NULL, space);	// get the first reg				if(reg1 != NULL)				{					tmp = GetRegCode(reg1);					program[instrNum].instr.RT = tmp;					oneInstr += tmp << 16;					reg2 = strtok(NULL, space);	// get the second operator					if(reg2 != NULL)					{						tmp = GetRegCode(reg2);						program[instrNum].instr.RS = tmp;						oneInstr += tmp << 21;						reg3 = new char[KEY_LENGTH];						reg3 = strtok(NULL, space);	// get the third operator						if(reg3 != NULL)						{							tmp = GetRegCode(reg3) << 16 >> 16;							oneInstr += tmp;							program[instrNum].instr.IM = tmp;							reg3 = strtok(NULL, space);							if(reg3 != NULL)		// error detection								return (unsigned)-1;						}					}				}				break;			// handle the J-format instructions			case 2:				tmp = GetOPCode(op);				oneInstr = tmp << 26;				program[instrNum].instr.OP = tmp;				program[instrNum].instr.SH = (unsigned)-1;				program[instrNum].instr.RS = (unsigned)-1;				program[instrNum].instr.RT = (unsigned)-1;				program[instrNum].instr.RD = (unsigned)-1;				program[instrNum].instr.FN = (unsigned)-1;				program[instrNum].instr.IM = (unsigned)-1;				reg1 = strtok(NULL, space);	// get the first reg				if(reg1 != NULL)				{					tmp = GetRegCode(reg1) << 6 >> 6;					oneInstr += tmp;					program[instrNum].instr.AD = tmp;					reg2 = strtok(NULL, space);	// get the second operator					if(reg2 != NULL)						return (unsigned)-1;				}				break;			// handle instruction jr			case 3:				tmp = GetOPCode(op);				oneInstr = tmp << 26;				program[instrNum].instr.OP = tmp;				tmp = GetFunct(op);				oneInstr += tmp;				program[instrNum].instr.FN = tmp;				program[instrNum].instr.RT = (unsigned)-1;				program[instrNum].instr.RD = (unsigned)-1;				program[instrNum].instr.SH = (unsigned)-1;				program[instrNum].instr.IM = (unsigned)-1;				program[instrNum].instr.AD = (unsigned)-1;				reg1 = strtok(NULL, space);	// get the first reg				if(reg1 != NULL)				{					tmp = GetRegCode(reg1);					program[instrNum].instr.RS = tmp;					oneInstr += tmp << 21;					reg2 = strtok(NULL, space);	// get the second operator					if(reg2 != NULL)						return (unsigned)-1;				}				break;			// handle instruction lw, sw			case 4:				tmp = GetOPCode(op);				oneInstr = tmp << 26;				program[instrNum].instr.OP = tmp;				program[instrNum].instr.FN = (unsigned)-1;				program[instrNum].instr.SH = (unsigned)-1;				program[instrNum].instr.IM = 0;				program[instrNum].instr.RD = (unsigned)-1;				program[instrNum].instr.AD = (unsigned)-1;				reg1 = strtok(NULL, space);	// get the first reg				if(reg1 != NULL)				{					tmp = GetRegCode(reg1);					program[instrNum].instr.RT = tmp;					oneInstr += tmp << 16;					reg2 = strtok(NULL, space);	// get the second operator					if(reg2 != NULL)					{						char *tmpreg = new char[KEY_LENGTH];						strcpy(tmpreg,reg2);		// back up reg2						reg3 = strtok(reg2, "(");	// detect if there is IM value						if(reg3 != NULL)			// there is						{							tmp = ( (unsigned int)atoi(reg3) ) << 16 >> 16;							program[instrNum].instr.IM = tmp;							oneInstr += tmp;							reg2 = strtok(NULL, ")");						}						else						// there is not						{							strcpy(reg2,tmpreg);						}						tmp = GetRegCode(reg2);						program[instrNum].instr.RS = tmp;						oneInstr += tmp << 21;					}				}				break;			}	// end of switch			return oneInstr;		} // end of one instruction		else	// find the definitions of labels		{			// If there is other things like data segment, this judgement			// should be applied for recognizing the start of code segment		//	if(!strcmp(op,"__start:") && flag == 0)		//		flag = 1;		//	else			{				op = strtok(op, " \t:");				if(op != NULL && flag)	// op is a label				{					labelTable[labelNum].offset = instrNum;					strcpy(labelTable[labelNum++].name, op);				}			}		}	}	return (unsigned)-2;	// if this is not an instruction}unsigned int Program::LoadInstr(const unsigned int PC){	if(PC/4 > instrNum || PC < 0)	{		cout<<"The PC address "<<PC<<" is out of bound!"<<endl;		assert(1);	}	if(PC%4 != 0)	{		cout<<"The PC address "<<PC<<" is an illegal instruction address!"<<endl;		assert(1);	}	if(PC/4 == instrNum)		return 0;	// Here, we return the 32-bit code of the fetched instruction by default.	// Then you can decode it by yourself. Otherwise, you may want to use the	// decoded structure provided by us, then you should use "return PC/4" here,	// and get the OP code by "prog.program[PC/4].instr.OP" in the simulator. The	// rest may be deduced similarly. Read the struct CodeLine and Instr for reference.	return program[PC/4].instrCode;}

⌨️ 快捷键说明

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