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

📄 privatefuncs.cpp

📁 MIPS32指令系统的汇编器。 在QUARTUS仿真环境中
💻 CPP
📖 第 1 页 / 共 4 页
字号:
#include "assembler.h"


void Assembler::GenFiles()
{
	//打开文件,到文件指针
	if( (DataFile=fopen("dmem32.mif","w+")) == NULL )
	{ 
		MessageBox(NULL,"文件打开错误","warning",MB_OK);
	}
	else 
	{
		fprintf( DataFile, "DEPTH = 1024;\nWIDTH = 32;\n\nADDRESS_RADIX = HEX;\nDATA_RADIX = HEX;\n\nCONTENT\nBEGIN\n" );
	}

	if( (ProgramFile=fopen("prgmip32.mif","w+")) == NULL )
	{ 
		MessageBox(NULL,"文件打开错误","warning",MB_OK);
	}
}

void Assembler::ShutFiles()
{
	fclose(DataFile);		 //关闭数据文件
	fclose(ProgramFile);	 //关闭指令文件
}

int Assembler::WriteProg()	  //将指令写入程序文件
{
	if ( BackWrite() )	//回填指令
		return -2;	//引用了不存在的标号名
	//至此,所有指令的32位指令码已经完成,现在将其转化为十六进制的形式
	list<My_CMD>::iterator i, iend;
	iend = COMMANDS.end();
	for ( i = COMMANDS.begin(); i != iend; i++ )
	{
		int temp[8] = { 0, 0, 0, 0, 0, 0, 0, 0 };
		int k, j;
		for ( k = 0; k < 8; k++ )
			for ( j = 0; j < 4; j++ )
				temp[k] += (i->Com[4*k+j]-48)*pow(2,3-j);
		for ( k = 0; k < 8; k++ )
		{
			switch ( temp[k] )
			{
			case 0:
			case 1:
			case 2:
			case 3:
			case 4:
			case 5:
			case 6:
			case 7:
			case 8:
			case 9:
				i->ComH[k] = temp[k]+48;
				break;
			case 10:
				i->ComH[k] = 'A';
				break;
			case 11:
				i->ComH[k] = 'B';
				break;
			case 12:
				i->ComH[k] = 'C';
				break;
			case 13:
				i->ComH[k] = 'D';
				break;
			case 14:
				i->ComH[k] = 'E';
				break;
			case 15:
				i->ComH[k] = 'F';
				break;
			default:
				break;
			}
		}
		i->ComH[k] = '\0';
	}
//	fprintf( ProgramFile, "DEPTH = 1024;\nWIDTH = 32;\n\nADDRESS_RADIX = HEX;\nDATA_RADIX = BIN;\n\nCONTENT\nBEGIN\n" );
	fprintf( ProgramFile, "DEPTH = 1024;\nWIDTH = 32;\n\nADDRESS_RADIX = HEX;\nDATA_RADIX = HEX;\n\nCONTENT\nBEGIN\n" );
	//以下是根据COMMANDS来写程序文件的,注意COMMANDS是一个list
	int oda = 0;
	for ( i = COMMANDS.begin(); i != iend && oda < 1024; i++, oda++ )
	{
		if ( CodeUnitUsed[i->Order] == true )
			return -1;	//地址交迭错误
		if ( oda != i->Order )
		{
			if ( oda == i->Order - 1 )
			{
				fprintf( ProgramFile, "\t" );
				fprintf( ProgramFile, "% x", oda );
				fprintf( ProgramFile, " : \t00000000;\n" );
			}
			else
			{
				fprintf( ProgramFile, "\t\t[" );
				fprintf( ProgramFile, "% x", oda );
				fprintf( ProgramFile, ".." );
				fprintf( ProgramFile, "% x", i->Order - 1 );
				fprintf( ProgramFile, "] : 00000000;\n" );
			}
			oda = i->Order;
		}

		fprintf( ProgramFile, "	" );
		fprintf( ProgramFile, "% x", i->Order );
		fprintf( ProgramFile, " : " );
//		fprintf( ProgramFile, i->Com );
		fprintf( ProgramFile, "\t" );
		fprintf( ProgramFile, i->ComH );
		fprintf( ProgramFile, ";\n" );
		CodeUnitUsed[i->Order] = true;
	}
	//////////////////////////////////
	if ( No_Com < 1024 )
	{
		fprintf( ProgramFile, "		[" );
		fprintf( ProgramFile, "% x", No_Com );
		fprintf( ProgramFile, "..3FF] : 00000000;\nENDS;" );
	}
	else 
		fprintf( ProgramFile, "\nENDS;" );

	return 0;	// 0 表示成功退出
}

int Assembler::BackWrite()
{
	if ( BACKTABLE.empty() )
		return 0;
	list<My_Back>::iterator i, iend;
	i = BACKTABLE.begin();
	iend = BACKTABLE.end();
	list<My_CMD>::iterator it, itend;
	it = COMMANDS.begin();
	itend = COMMANDS.end();
	int ta;		//暂存一个IDNAME的地址
	for ( ; i != iend; i++ )
	{
		while ( i->Order != it->Order )		//先定位该回填的指令,以COMMANDS链中
		{
			it++;
		}
//		cout << i->Order << '\t' << i->Name << endl;
		ta = SegNameToAddr( i->Name );
// 		cout << i->Name << '\t' << ta << endl;
// 		cout << "old: " << it->Com << endl;
		if ( ta == -1 )		//该标号名不存在
			return -1;
		for( int j = 0; ta != 0 && j < 16; j++ )
		{
			it->Com[31-j] = ta%2 + 48; //注意char与int的转换
			ta = ta/2;
		}
 //		cout << "\nnew: " << it->Com << endl;
		for (; j < 16; j++ )
			it->Com[31-j] = '0';
	}
	return 0;	// 0 表示成功退出
}

int Assembler::AddBackID()		//将待回填的标号保存起来,保存到BACKTABLE中
{
	My_Back temp;
 	temp.Order = No_Com;	//待回填指令的地址
	temp.Name = new char[LengthOfID];
	int it = 0;
	while ( TOKEN.TokenName[it] != '\0' && it < LengthOfID )
	{
		temp.Name[it] = TOKEN.TokenName[it];
		it++;
	}
	if ( it < LengthOfID ) 
		temp.Name[it] = '\0';
	else
		return -1;

	BACKTABLE.push_back( temp );
 //	cout << "in addback: " << temp.Order << '\t' << temp.Name << endl;
	return 0;	// 0 表示成功退出
}

int Assembler::AddNormalSegID()
									//如果最近采用的是27号产生式,则IDNAME是指令标号,顺序保存到标号表SEGID
									//如果标号有重复则错误退出, return 21;否则正确退出,return 0;
{
	My_SegID temp;
	temp.Order = No_Com;
	temp.Name = new char[LengthOfID];
	int it = 0;
	while ( TOKEN.TokenName[it] != '\0' && it < LengthOfID )
	{
		temp.Name[it] = TOKEN.TokenName[it];
		it++;
	}
	if ( it < LengthOfID ) 
		temp.Name[it] = '\0';
	else
		return -1;

//	cout << temp.Name << endl;

	SEGID.push_back( temp );

	list<My_SegID>::iterator i, iend;
	iend = SEGID.end();
	iend--;
	for ( i = SEGID.begin(); i != iend; i++ )
	{
/*		cout << "into for" << endl
			 << "i->Name: " << i->Name << endl
			 << "temp.Name: " << temp.Name << endl;
*/		if ( StrCmp(i->Name,temp.Name) )
			return -1;		//如果有重名,则错误退出
	}
//	cout << temp.Order << '\t' << temp.Name << endl;
	return 0;	// 0 表示成功退出
}

int Assembler::AddStartSegID()
									//如果最近采用的是15号产生式,则IDNAME是起始指令标号,保存到标号表SEGID的最前面
									//如果标号有重复则错误退出, return 21;否则正确退出,return 0;
{
	My_SegID temp;
	temp.Order = No_Com;
	temp.Name = new char[LengthOfID];
	int it = 0;
	while ( TOKEN.TokenName[it] != '\0' && it < LengthOfID )
	{
		temp.Name[it] = TOKEN.TokenName[it];
		it++;
	}
	if ( it < LengthOfID ) 
		temp.Name[it] = '\0';
	else
		return -1;
	
	SEGID.push_front( temp );

	list<My_SegID>::iterator i, iend;
	iend = SEGID.end();
	i = SEGID.begin();
	i++;
	for ( ; i != iend; i++ )
		if ( StrCmp(i->Name,temp.Name) )
			return -1;		//如果有重名,则错误退出
	return 0;	// 0 表示成功退出
}

int Assembler::StoreVar()		//将变量标识符保存到VAR,如果失败则return 23;退出
{
	My_Var temp;
 	temp.Order = No_Var;
	temp.Name = new char[LengthOfID];
	int it = 0;
//	cout << TOKEN.TokenName << endl;
	while ( TOKEN.TokenName[it] != '\0' && it < LengthOfID )
	{
		temp.Name[it] = TOKEN.TokenName[it];
		it++;
	}
	if ( it < LengthOfID ) 
		temp.Name[it] = '\0';
	else
		return -1;

	VAR.push_back( temp );
	
	list<My_Var>::iterator i, iend;
	iend = VAR.end(); 
	iend--;
	i = VAR.begin();
/*	cout << i->Name << endl
		 << iend->Name << endl
		 << temp.Name << endl;
*/	for ( ; i != iend; i++ )
	{
		if ( StrCmp(i->Name,temp.Name) )
			return -1;		//如果有重名,则错误退出
	}
//	cout << "VAR's addr: " << temp.Order << '\t' << "VAR's name: " << temp.Name << endl;
	return 0;	// 0 表示成功退出
}

int Assembler::Deduction( int NumOfVN )
{
	int i;
	STACK.pop();
	for ( i = 0; i < DepthOfRule; i++ )
					//依据产生式右部的长度,循环地将产生式右部装入栈内
	{
		if ( SyntacticRules[NumOfVN][i] == 0 )
					//如果编号为NumOfVN的规则的右部第i位为零,说明产生式推导完毕
			break;
		else
		{
			STACK.push( SyntacticRules[NumOfVN][i] );
			if ( STACK.size() > StackSize )
				return 5;		// 栈满报警
		}
	}

	return 0;					//说明产生式推导成功完毕, 0 表示成功退出
}

char Assembler::ReadOneChar( FILE* SourceFileName )
{
	char ch;
	while ( !feof( SourceFileName ) )
	{
		ch = getc( SourceFileName );
		if ( ch != ' ' && ch != '\t' )
			return ch;
	}
	return -1;
}

char Assembler::ReadNextChar( FILE* SourceFileName )
{
	if ( !feof( SourceFileName ) )
		return getc( SourceFileName );
	exit(0);	//文件结束,强制结束程序
}

bool Assembler::StrCmp( char* s, char* t ) //比较两个字符串,如果相同则返回true,否则返回false
{
	if ( s=="" || t=="" )
		return false;
	int i = 0;
	for ( ;(s[i]!='\0') && (s[i]==t[i]) && (t[i]!='\0'); i++);
	if ( (s[i]=='\0') && (t[i]=='\0') )
		return true;
	return false;
}

int Assembler::ConstructCOMMANDS()	//将CMD按照指令顺序保存到指令链COMMANDS,如果失败则return 10;退出
{//	static int counter = 0;counter++; cout << "counter: " << counter << endl;
	My_CMD temp;
	temp.Order = No_Com;	//指令地址
	//以下两条语句是为了寻找这条指令可能存在的指令标号,如果存在,则一定是最近的一个SEGID元素,即用在SEGID链的链尾
	if ( COMMANDS.empty() )
	{
		temp.JSegName = "";
	}
	else
	{
		list<My_SegID>::iterator iend = SEGID.end();
		iend--;
		if ( iend->Order == No_Com )
		{
			temp.JSegName = new char[LengthOfID];
			int it = 0;
			while ( iend->Name[it] != '\0' && it < LengthOfID )
			{
				temp.JSegName[it] = iend->Name[it];
				it++;
			}
			if ( it < LengthOfID ) 
				temp.JSegName[it] = '\0';
			else
				return -1;
		}
		else
			temp.JSegName = "";
	}

	for ( int j = 0; j < 32; j++ )
	{
		temp.Com[ j ] = CMD[ 31-j ];
 //		cout << CMD[ 31-j ];
	}
 //	cout << endl;
	temp.Com[32] = '\0';

	COMMANDS.push_back( temp );
	if ( COMMANDS.empty() )
		return -1;
// 	cout << No_Com << ' ' << temp.Com << endl;
	if ( No_Com < 1024 )
		No_Com++;
	else
		return -1;
	for ( int i = 0; i < 32; i++ )
	{
		CMD[i] = '0';	//清空CMD
//		cout << CMD[i];
	}


	return 0;	// 0 表示成功退出
}

int Assembler::ConstructCMD()	// 将当前单词翻译为二进制码,存入CMD,如果翻译失败则return 10;退出
{
	int i;
	bool flag = false;	//此标志用来指示是否有如BUF+4这样的指令
	switch ( STACK.top() )
	{
	case T_RCOM:
		{
			if ( TOKEN.TokenName[0] == 'o' || TOKEN.TokenName[01] == 'O' )	// or
				CMD[5] = CMD[2] = CMD[0] = '1';
			else if ( TOKEN.TokenName[0] == 'x' || TOKEN.TokenName[0] == 'X' )	// xor											
				CMD[5] = CMD[2] = CMD[1] = '1';
			else if ( TOKEN.TokenName[0] == 'n' || TOKEN.TokenName[0] == 'N' )	// nor												
				CMD[5] = CMD[2] = CMD[1] = CMD[0] = '1';
			else if ( TOKEN.TokenName[0] == 'a' || TOKEN.TokenName[0] == 'A' )	// add,addu,and
			{
				if ( TOKEN.TokenName[1] == 'n' || TOKEN.TokenName[1] == 'N' ) //and
					CMD[5] = CMD[2] = '1';
				else if ( TOKEN.TokenName[3] == 'u' || TOKEN.TokenName[3] == 'U' ) //addu
					CMD[5] = CMD[0] = '1';
				else														// add
					CMD[5] = '1';
			}
			else 				// sub,subu,slt,sltu,sllv,srlv,srav
			{
				if ( TOKEN.TokenName[1] == 'u' || TOKEN.TokenName[1] == 'U' ) 
				{
					if ( TOKEN.TokenName[3] == 'u' || TOKEN.TokenName[3] == 'U' )	// subu
						CMD[5] = CMD[1] = CMD[0] = '1';
					else															// sub
						CMD[5] = CMD[1] = '1';
				}
				else if ( TOKEN.TokenName[1] == 'l' || TOKEN.TokenName[1] == 'L' ) 
				{
					if ( TOKEN.TokenName[2] == 't' || TOKEN.TokenName[2] == 'T' )	
					{
						if ( TOKEN.TokenName[3] == 'u' || TOKEN.TokenName[3] == 'U' )// sltu
							CMD[5] = CMD[3] = CMD[1] = CMD[0] = '1';
						else															// slt
							CMD[5] = CMD[3] = CMD[1] = '1';
					}
					else															// sllv
						CMD[2] = '1';
				}
				else	
				{
					if ( TOKEN.TokenName[2] == 'a' || TOKEN.TokenName[2] == 'A' )	// srav
						CMD[2] = CMD[1] = CMD[0] = '1';
					else															// srlv
						CMD[2] = CMD[1] = '1';
				}
			}
			return 0;	// 0 表示成功退出
		}
	case T_SRCOM:
		{
			CMD[3] = '1';									// jr
			return 0;	// 0 表示成功退出
		}
	case T_SLLRCOM:
		{
			if ( TOKEN.TokenName[1] == 'l' || TOKEN.TokenName[1] == 'L' )	// sll
				;
			else if ( TOKEN.TokenName[2] == 'l' || TOKEN.TokenName[2] == 'L' )	// srl												// sw
				CMD[1] = '1';
			else															// sra	
				CMD[1] = CMD[0] = '1';
			return 0;	// 0 表示成功退出
		}
	case T_ICOM:
		{
			if ( TOKEN.TokenName[0] == 'o' || TOKEN.TokenName[01] == 'O' )	// ori
				CMD[29] = CMD[28] = CMD[26] = '1';
			else if ( TOKEN.TokenName[0] == 'x' || TOKEN.TokenName[0] == 'X' )	// xori												// sw
				CMD[29] = CMD[28] = CMD[27] = '1';

⌨️ 快捷键说明

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