简单的汇编语言译码程序

这里实现的是汇编语言译码。

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.在输入指令时,务必将第一行置空,排除第一行不能正常翻译的现象。

原文地址:https://www.cnblogs.com/liugl7/p/4205923.html