📄 privatefuncs.cpp
字号:
#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 + -