在用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;
}