zoukankan      html  css  js  c++  java
  • 简单的汇编语言译码程序

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

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

  • 相关阅读:
    手机进水不要慌,四个步骤告诉您正确处理方法!
    2021-08-17:学习项目代码流程
    Docker使用Centos镜像安装Openssh服务
    OpenResty简介、下载流程、简单教学
    go接收者和锁注意事项
    PHPstorm精进
    centos7找回root密码
    功能测试
    删除排序数组中的重复项
    Java多线程
  • 原文地址:https://www.cnblogs.com/liugl7/p/4205923.html
Copyright © 2011-2022 走看看