这里实现的是汇编语言译码。
eg:这里的一段MIPS汇编语言指令
ORI $1 $0 7 ORI $2 $0 4 ADD $3 $1 $2 SUB $4 $1 $2 OR $5 $3 $4 AND $6 $3 $4 ORI $7 $6 $12 MOVE $8 $2 SW $1 3 ($9 ) LW $2 3 ($9 ) BEQ $2 $8 -10 INC $2 JAL 01001010010
翻译为二进制之后为:
01001000 00000001 00000000 00000111 01001000 00000010 00000000 00000100 00000000 00100000 00011000 00000000 00000100 00100000 00100000 00000000 01000000 01100000 00101000 00000000 01000100 01100000 00110000 00000000 01001000 11000111 00000000 00000000 10000000 01000000 01000000 00000000 10011001 00100001 00000000 00000011 10011101 00100010 00000000 00000011 11000000 01001000 11111111 11110110 00001100 00000010 00000000 00000000 110010** ******** ******** ********
下面是实现代码
#include <iostream> #include <string> #include <stack> #include <list> #include <fstream> #include <cctype> #include <cstdlib> using namespace std; const long COUNT=100; string data[COUNT]; struct result{ string elems; }; result outfile[COUNT]; //处理结果是把string data[COUNT]转化为二进制指令码存进outfile[COUNT]中 int count=0;//用来记录有效数据的个数 void datain(){ ifstream insmemary("inmemary.txt"); while(getline(insmemary,data[count])){ ++count; } insmemary.close(); } //把十进制转化为二进制 string cnumts(int a){ switch(a){ case 0:{ return "00000"; break; } case 1:{ return "00001"; break; } case 2:{ return "00010"; break; } case 3:{ return "00011"; break; } case 4:{ return "00100"; break; } case 5:{ return "00101"; break; } case 6:{ return "00110"; break; } case 7:{ return "00111"; break; } case 8:{ return "01000"; break; } case 9:{ return "01001"; break; } case 10:{ return "01010"; break; } case 11:{ return "01011"; break; } case 12:{ return "01100"; break; } case 13:{ return "01101"; break; } case 14:{ return "01110"; break; } case 15:{ return "01111"; break; } case 16:{ return "10000"; break; } case 17:{ return "10001"; break; } case 18:{ return "10010"; break; } case 19:{ return "10011"; break; } case 20:{ return "10100"; break; } case 21:{ return "10101"; break; } case 22:{ return "10110"; break; } case 23:{ return "10111"; break; } case 24:{ return "11000"; break; } case 25:{ return "11001"; break; } case 26:{ return "11010"; break; } case 27:{ return "11011"; break; } case 28:{ return "11100"; break; } case 29:{ return "11101"; break; } case 30:{ return "11110"; break; } case 31:{ return "11111"; break; } } } string ch(string a){ int q=atoi(a.c_str()); return cnumts(q); }//将相应序号转化为二进制数字符串 /* *f函数将二进制数转换为十进制数; */ int f(string s){ int a=0; for(int i=0;i<s.length();i++){ a=a*2+(s[i]-‘0‘); } return a; } /** * t函数将十进制数转换为二进制字符串 */ string t(int a){ string s; while(a){ string temp="1"; temp[0]=a%2+‘0‘; s=temp+s; a/=2; } return s; } //将立即数转化为16位二进制数字符串 string chr(string ab){ if(ab[0]!=‘-‘){ int q=atoi(ab.c_str()); string out=""; while(q>1){ if(q%2==0){ q=q/2; out+="0"; } else{ q=(q-1)/2; out+="1"; } } if(q%2==0){ out+="0"; } else{ out+="1"; } while(out.length()<16){ out+="0"; } string temp=""; for(int i=out.length()-1;i>=0;--i){ temp+=out[i]; } return temp; } else{ string a=ab.substr(1,ab.length()-1); int q=atoi(a.c_str()); string temp2=t(q); for(int l=0;l<temp2.length();++l){ if(temp2[l]==‘0‘){ temp2[l]=‘1‘; } else{ temp2[l]=‘0‘; } } int lon=temp2.length(); int result=f(temp2)+1; string temp3=""; while(result>1){ if(result%2==0){ result/=2; temp3="0"+temp3; } else { result=(result-1)/2; temp3="1"+temp3; } } if(result==0){ temp3="0"+temp3; } else{ temp3="1"+temp3; } while(temp3.length()<lon){ temp3="0"+temp3; } while(temp3.length()<16){ temp3="1"+temp3; } return temp3; } } result change(string temp){ result outr; string op2=temp.substr(0,4);//处理操作码有四个字母的指令 if(op2=="ADDI"){ outr.elems+="000000"; outr.elems+=ch(temp.substr(10,2)); //存入rs字段 outr.elems+=ch(temp.substr(6,2)); //存入rt字段 outr.elems+=chr(temp.substr(12,temp.length()-11)); return outr; } else if(op2=="MOVE"){ outr.elems+="100000"; outr.elems+=ch(temp.substr(10,2)); //存入rs字段 outr.elems+="00000"; //存入rt字段 outr.elems+=ch(temp.substr(6,2)); //存入rd字段 outr.elems+="00000000000"; //尾位补零 return outr; } else if(op2=="HALT"){ outr.elems+="111111"; outr.elems+="00000000000000000000000000"; return outr; } string op=temp.substr(0,3);//处理操作码有三个字母的指令 if(op=="ADD"){ outr.elems="000000"; outr.elems+=ch(temp.substr(9,2)); //存入rs字段 outr.elems+=ch(temp.substr(12,2)); //存入rt字段 outr.elems+=ch(temp.substr(5,2)); //存入rd字段 outr.elems+="00000000000"; //尾位补零 return outr; } else if(op=="SUB"){ outr.elems="000001"; outr.elems+=ch(temp.substr(9,2)); //存入rs字段 outr.elems+=ch(temp.substr(12,2)); //存入rt字段 outr.elems+=ch(temp.substr(5,2)); //存入rd字段 outr.elems+="00000000000"; //尾位补零 return outr; } else if(op=="INC"){ outr.elems="000011"; outr.elems+="00000"; //存入rs字段 outr.elems+=ch(temp.substr(5,2)); //存入rt字段 outr.elems+="00000"; //存入rd字段 outr.elems+="00000000000"; //尾位补零 return outr; } else if(op=="DEC"){ outr.elems="000100"; outr.elems+="00000"; //存入rs字段 outr.elems+=ch(temp.substr(5,2)); //存入rt字段 outr.elems+="00000"; //存入rd字段 outr.elems+="00000000000"; //尾位补零 return outr; } else if(op=="AND"){ outr.elems="010001"; outr.elems+=ch(temp.substr(9,2)); //存入rs字段 outr.elems+=ch(temp.substr(12,2)); //存入rt字段 outr.elems+=ch(temp.substr(5,2)); //存入rd字段 outr.elems+="00000000000"; //尾位补零 return outr; } else if(op=="ORI"){ outr.elems="010010"; outr.elems+=ch(temp.substr(9,2)); //存入rs字段 outr.elems+=ch(temp.substr(5,2)); //存入rt字段 outr.elems+=chr(temp.substr(12,temp.length()-11)); return outr; } else if(op=="BEQ"){ outr.elems="110000"; outr.elems+=ch(temp.substr(5,2)); //存入rs字段 outr.elems+=ch(temp.substr(9,2)); //存入rt字段 outr.elems+=chr(temp.substr(12,temp.length()-11)); return outr; } else if(op=="JAL"){ outr.elems="110010"; outr.elems+="**************************"; return outr; } string op3=temp.substr(0,2);//处理操作码有两个字母的指令 if(op3=="OR"){ outr.elems="010000"; outr.elems+=ch(temp.substr(8,2)); //存入rs字段 outr.elems+=ch(temp.substr(11,2)); //存入rt字段 outr.elems+=ch(temp.substr(4,2)); //存入rd字段 outr.elems+="00000000000"; //尾位补零 return outr; } else if(op3=="SW"){ outr.elems="100110"; outr.elems+=ch(temp.substr(12,2)); //存入rs字段 outr.elems+=ch(temp.substr(4,2)); //存入rt字段 outr.elems+=chr(temp.substr(7,3)); //存入immediate字段 return outr; } else if(op3=="LW"){ outr.elems="100111"; outr.elems+=ch(temp.substr(12,2)); //存入rs字段 outr.elems+=ch(temp.substr(4,2)); //存入rt字段 outr.elems+=chr(temp.substr(7,3)); //存入immediate字段 return outr; } else if(op3=="JR"){ outr.elems="110011"; outr.elems+=ch(temp.substr(4,2)); //存入rs字段 outr.elems+="000000000000000000000"; return outr; } string op1=temp.substr(0,1);//处理操作码有一个字母的指令 if (op1=="J"){ outr.elems+="110001"; outr.elems+="**************************"; return outr; } }//实现指令string temp到result的转化 void dataout(){ ofstream out("InsMemary.txt"); for (int i = 0; i < count; ++i){ int count1=0; int count2=0; for (int j = 0; j < 32; ++j) { out<<outfile[i].elems[j]; ++count1; if (count1==8&&count2!=3){ count1=0; out<<endl; ++count2; }//32位的数据按照8位输出 } out<<endl; } out.close(); }//将outfile[COUNT]里面的文件输出到“InsMemary.txt里面” int main(){ datain(); for (int i = 0; i <count ; ++i){ outfile[i].elems=change(data[i]).elems; } dataout(); }
编译器
注意指令输入务必遵循以下规则:
eg:ADD $10 $12 $23
eg:ADDI $1 $2 123
1.即输入操作码与寄存器之间有一个空格间隔;寄存器号可以输入两位数,如果是一位数序号的寄存器,在第二位用空格表示。
2.J 指令需要PC的地址,所以这里暂时按填充*******处理
3.SW,LW,语句的immediate可以输入三位数,不够三位的用空格代替
时间: 2024-10-14 11:13:50