機器碼轉匯編指令


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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM