简单的汇编语言译码程序
2015-01-06 14:03
806 查看
这里实现的是汇编语言译码。
eg:这里的一段MIPS汇编语言指令
下面是转化成的二进制码
00000101
00000000
00010001
01001010
00001001
00000000
00010010
01001010
00000000
10011000
01010001
00000010
00000000
10100000
01110010
00000110
00000000
10101000
01010001
01000010
00000000
10110000
01110010
01000110
00110011
00000000
00110011
00001010
00000000
00000000
00010101
00001100
00000000
00000000
00010100
00010000
00000000
10111000
11000000
10000010
00000000
00000000
00011000
10011110
00000000
00000000
00010111
10011010
00000000
00000000
00011000
10011110
00000010
00000000
11010111
11000010
00000000
11001000
10110110
00000010
00000000
11001000
10010001
00000011
00010001
00000000
00000000
11000100
00010011
00000000
00000000
11001000
00000000
00000000
00000000
11111100
00000000
11001000
01110100
00000010
00000000
00000000
11100000
11001111
下面是实现代码
注意指令输入务必遵循以下规则:
eg:ADD $10 $12 $23
eg:ADDI $1 $2 123
1.即输入操作码与寄存器之间有一个空格间隔;寄存器号可以输入两位数,如果是一位数序号的寄存器,在第二位用空格表示。
2.SW,LW,语句的immediate可以输入三位数,不够三位的用空格代替
3.在输入指令时,务必将第一行置空,排除第一行不能正常翻译的现象。
eg:这里的一段MIPS汇编语言指令
AND $22 $19 $18 ORI $17 $16 5 ORI $18 $16 9 ADD $19 $18 $17 SUB $20 $19 $18 OR $21 $18 $17 AND $22 $19 $18 ADDI $19 $17 51 INC $21 DEC $20 MOVE $23 $22 LW $24 0 ($16) SW $23 0 ($16) LW $24 0 ($16) BEQ $22 $23 2 ADD $25 $21 $22 J 5 ADD $25 $28 $17 JAL 19 HALT ADD $25 $19 $20 JR $31
下面是转化成的二进制码
00000101
00000000
00010001
01001010
00001001
00000000
00010010
01001010
00000000
10011000
01010001
00000010
00000000
10100000
01110010
00000110
00000000
10101000
01010001
01000010
00000000
10110000
01110010
01000110
00110011
00000000
00110011
00001010
00000000
00000000
00010101
00001100
00000000
00000000
00010100
00010000
00000000
10111000
11000000
10000010
00000000
00000000
00011000
10011110
00000000
00000000
00010111
10011010
00000000
00000000
00011000
10011110
00000010
00000000
11010111
11000010
00000000
11001000
10110110
00000010
00000000
11001000
10010001
00000011
00010001
00000000
00000000
11000100
00010011
00000000
00000000
11001000
00000000
00000000
00000000
11111100
00000000
11001000
01110100
00000010
00000000
00000000
11100000
11001111
下面是实现代码
#include <iostream> #include <string> #include <stack> #include <list> #include <fstream> #include <cctype> #include <cstdlib> #include <cstdio> 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; } string addr(int a){ string temp=t(a); while(temp.length()<26){ temp="0"+temp; } return temp; } //将JAL J指令中的addr..转换为26位二进制码 //将立即数转化为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+="000010"; outr.elems+=ch(temp.substr(10,2)); //存入rs字段 outr.elems+=ch(temp.substr(6,2)); //存入rt字段 outr.elems+=chr(temp.substr(12,3)); 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(13,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(13,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"; // 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(13,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,3)); 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,3)); return outr; } else if(op=="JAL"){ outr.elems="110010"; int r=atoi(temp.substr(4,3).c_str()); outr.elems+=addr(r); 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(12,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"; int e=atoi(temp.substr(2,3).c_str()); outr.elems+=addr(e); return outr; } }//实现指令string temp到result的转化 void dataout(){ using namespace std; ofstream out("InsMemary1.txt"); for (int i = 1; i <count-1; ++i){ for (int j = 24; j < 32; ++j) { out<<outfile[i].elems[j]; } out<<endl; for (int j = 16; j < 24; ++j) { out<<outfile[i].elems[j]; } out<<endl; for (int j = 8; j < 16; ++j) { out<<outfile[i].elems[j]; } out<<endl; for (int j = 0; j < 8; ++j) { out<<outfile[i].elems[j]; } out<<endl; } out.close(); }//将outfile[COUNT]里面的数据输出到“InsMemary.txt里面” int main(){ for(int i=0;i<COUNT;++i){ data[i]=""; } datain(); for (int i = 0; i <count ; ++i){ outfile[i].elems=change(data[i]).elems; } dataout(); system("pause"); }
注意指令输入务必遵循以下规则:
eg:ADD $10 $12 $23
eg:ADDI $1 $2 123
1.即输入操作码与寄存器之间有一个空格间隔;寄存器号可以输入两位数,如果是一位数序号的寄存器,在第二位用空格表示。
2.SW,LW,语句的immediate可以输入三位数,不够三位的用空格代替
3.在输入指令时,务必将第一行置空,排除第一行不能正常翻译的现象。
相关文章推荐
- 一段简单c程序的汇编语言学习(ubuntu+x86)
- 32位汇编语言学习笔记(28)--一个简单的光标控制程序
- 一段简单c程序的汇编语言学习(ubuntu+x86)
- 一段简单c程序的汇编语言学习(ubuntu+x86)
- 汇编语言简单小程序——运算类编程实验
- C++反汇编揭秘1 – 一个简单C++程序反汇编解析 (Rev. 3)
- Winform程序多语言国际化实现的简单方法
- 一个在开发板上运行的超简单汇编程序--何军
- C++反汇编揭秘1 – 一个简单C++程序反汇编解析 (Rev. 3)
- 利用汇编语言开发盗QQ密码程序
- 同一张光盘安装的VC为什么调试时有的机子是程序步,有的是汇编语言呢?
- DirectX 9高层着色语言介绍1——引言、简单例子、汇编语言和编译对象
- 一段简单的汇编程序,显示键盘按健的扫描码和ASCII码
- c 语言实现的简单屏幕烟花程序
- C++反汇编揭秘1 – 一个简单C++程序反汇编解析 (Rev. 3) - [C/C++]
- Linux下最简单的汇编程序
- 初学 Delphi 嵌入汇编[24] - 汇编语言的简单数据类型
- 汇编语言中常用进制数据输出的程序实现
- DirectX 9高层着色语言介绍1 —— 引言、简单例子、汇编语言和编译对象
- C++反汇编揭秘1 一个简单的C++程序反汇编解析