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