• 机器码转汇编指令


    在用logisim初步画完CPU电路后,配合educoder调试电路。提交代码到educoder后,后台会检测错误信息,根据报错信息中的周期数或者PC值,可以找到错误的指令机器码。
    但是机器码太抽象,因此使用下面的程序将指令机器码翻译成指令名称,进而继续调试电路。

    /*
     	32位MIPS指令翻译器
    	输入一条16进制的指令
    	输出该指令的详细信息
     */
    
    
    #include<iostream>
    #include<string>
    #include<cctype>
    #include<bitset>
    #include<map>
    
    using namespace std;
    
    typedef unsigned int IRType;	//存储32位指令
    
    struct INST{
    	string name;
    	string type;
    	string func;
    };
    
    //24条MIPS指令
    map<string, INST> transTable = {	//can not be const
    	{"000000000000",{ .name="sll", .type="R", .func="逻辑左移" }},
    	{"000000000011",{ .name="sra", .type="R", .func="算术右移"  }},
    	{"000000000010",{ .name="srl", .type="R", .func="逻辑右移"  }},
    	{"000000100000",{ .name="add", .type="R", .func="符号加"  }},
    	{"000000100001",{ .name="addu", .type="R", .func="无符号加"  }},
    	{"000000100010",{ .name="sub", .type="R", .func="符号减"  }},
    	{"000000100100",{ .name="and", .type="R", .func="与"  }},
    	{"000000100101",{ .name="or", .type="R", .func="或"  }},
    	{"000000100111",{ .name="nor", .type="R", .func="或非"  }},
    	{"000000101010",{ .name="slt", .type="R", .func="比较大小,小于则寄存器置1(有符号)"  }},
    	{"000000101011",{ .name="sltu", .type="R", .func="比较大小,小于则寄存器置1(无符号)"  }},
    	{"000000001000",{ .name="jr", .type="J", .func="跳转至寄存器"  }},
    	{"000000001100",{ .name="syscall", .type="SYSCALL", .func="系统调用"  }},
    	{"000010"      ,{ .name="j", .type="J", .func="跳转"  }},
    	{"000011"      ,{ .name="jal", .type="J", .func="跳转并链接"  }},
    	{"000100"      ,{ .name="beq", .type="I", .func="相等时跳转"  }},
    	{"000101"      ,{ .name="bne", .type="I", .func="不等时跳转"  }},
    	{"001000"      ,{ .name="addi", .type="I", .func="符号加立即数"  }},
    	{"001100"      ,{ .name="andi", .type="I", .func="与立即数"  }},
    	{"001001"      ,{ .name="addiu", .type="I", .func="无符号立即数加法"  }},
    	{"001010"      ,{ .name="slti", .type="I", .func="比较大小,小于立即数则寄存器置1(有符号)"  }},
    	{"001101"      ,{ .name="ori", .type="I", .func="或立即数"  }},
    	{"100011"      ,{ .name="lw", .type="I", .func="内存加载字到寄存器堆"  }},
    	{"101011"      ,{ .name="sw", .type="I", .func="寄存器存储字到内存"  }}
    };
    
    string HexToBin( string irHex );
    
    int main()
    {
    	string irHex, irBin;
    	string opCode, funct;
    
    
    	cout << "请输入32位16进制指令:(如12200001)" << endl;
    	while( cin >> irHex ){
    		irBin = HexToBin(irHex);
    		cout << "bianry instruction: " << irBin << endl;	//test
    
    		opCode = irBin.substr(0,6);	//不包括最后一位
    		funct = irBin.substr(26,-1);
    
    		if( transTable.find(opCode+funct) != transTable.end() ){
    			cout << "name : " << transTable[(opCode+funct)].name << endl;
    			cout << "type : " << transTable[(opCode+funct)].type <<  " | "
    				"function : " << transTable[(opCode+funct)].func <<endl;
    		}
    		else if( transTable.find(opCode) != transTable.end() ){
    			cout << "name : " << transTable[(opCode)].name << endl;
    			cout << "type : " << transTable[(opCode)].type <<  " | "
    				"function : " << transTable[(opCode)].func <<endl;
    		
    		}
    		else{
    			cout << "this instruction isn't included." << endl;
    		}
    	}
    	
    	return 0;
    }
    
    
    string HexToBin( string irHex )
    {
    	const string numbers = "0123456789";
    	string irBin;
    	IRType irDec = 0;
    
    	for( string::iterator itr = irHex.begin();  itr != irHex.end();  itr++ ){
    		irDec *= 16;
    
    		if( numbers.find(*itr) != string::npos ){
    			irDec += ( (*itr) - '0' );
    		}else{
    			( *itr ) = tolower(*itr);
    			irDec += ( (*itr) - 'a' + 10 );
    		}
    	}
    
    	//cout << irDec << endl;	//test
    	irBin = 1;
    	irBin = bitset<sizeof(IRType)*8>((int)irDec).to_string();
    
    	return irBin;
    }
    
  • 相关阅读:
    使用socket BPF/Linux内核工程导论——网络:Filter(LSF、BPF、eBPF)
    使用Iperf工具测试android系统网络wifi的吞吐量wifithrougput
    html input中 button和submit的区别
    Linux转发性能评估与优化(转发瓶颈分析与解决方案)
    交叉编译器 arm-linux-gnueabi 和 arm-linux-gnueabihf 的区别
    MySQL查询不区分大小写的sql写法
    Docker镜像保存save、加载load
    将Spring-boot应用部署到Docker容器
    Docker 安装使用
    Scalatra文件下载时中文乱码
  • 原文地址:https://www.cnblogs.com/friedCoder/p/12308496.html
Copyright © 2020-2023  润新知