Decoding MIPS Instructions from a Binary File:

/// 
/// Decode MIPS Instructions 
///

#include <fstream>
#include <iostream>
#include <cmath>
#include <vector>

using namespace std;

void readArray(char* a, int size)
{
	fstream fout("mips-test.bin", ios::in | ios::binary);
	if(fout)
	{
		fout.read(reinterpret_cast<char*>(a), size * sizeof(char));
		fout.close();
	}
	else
		cout << "Error!\n";
}

void printBinary(char c)
{
	for(int i = 7; i >=0; --i){
		cout << ((c & ( 1 << i)) ? '1' : '0');
	}
}

string printBinary2(char c)
{
	string a = "";
	for(int i = 7; i >=0; --i){
		a.push_back( ((c & ( 1 << i)) ? '1' : '0') );
	}
	return a;
}

void whatAreYou(string a)
{
	string format = "";
	int opcode = 0;
	int exp = 5;
	int rs =  0;
	int rt =  0;
	int rd =  0;
	int imm = 0;
	int jmp = 0;


	// Determine the Opcode.
	for(char x = 0; x < 6; ++x){ 
		if(a.at(x) == '1')
			opcode += pow(2,exp);
		--exp;
	}

	// Determine the Format.
	if(opcode == 0)
		format = "R-Format";
	else if(opcode == 2 || opcode == 3)
		format = "J-Format";
	else
		format = "I-Format";
		
	// Print those things.
	cout << '\n' << "Format:      " << format 
		 << '\n' << "Opcode:      " << opcode;

	// Determine Register values (if any).
	if(opcode == 0){

		exp = 4;
		for(char x = 6; x < 11; ++x){
			if(a.at(x) == '1')
				rs += pow(2,exp);
			--exp;
		}

		exp = 4;
		for(char x = 11; x < 16; ++x){
			if(a.at(x) == '1')
				rt += pow(2,exp);
			--exp;
		}

		exp = 4;
		for(char x = 16; x < 21; ++x){
			if(a.at(x) == '1')
				rd += pow(2,exp);
			--exp;
		}


		cout << '\n' << "Rs Register: " << rs
			 << '\n' << "Rt Register: " << rt
		 	 << '\n' << "Rd Register: " << rd;
	}
	else if(opcode != 2 && opcode != 3){

		exp = 4;
		for(char x = 6; x < 11; ++x){
			if(a.at(x) == '1')
				rs += pow(2,exp);
			--exp;
		}

		exp = 4;
		for(char x = 11; x < 16; ++x){
			if(a.at(x) == '1')
				rd += pow(2,exp);
			--exp;
		}

		
		cout << '\n' << "Rs Register: " << rs
			 << '\n' << "Rd Register: " << rd;
	}
	
	// Immediate
	if(opcode != 0 && opcode != 2 && opcode != 3){
	
		exp = 15;
		for(char x = 16; x < 32; ++x){
			if(a.at(x) == '1')
				imm += pow(2,exp);
			--exp;
		}


		cout << '\n' << "Immediate:   " << imm;
	}

	// Jump Address
	if(opcode == 2 || opcode == 3){

		exp = 25;
		for(char x = 6; x < 32; ++x){
			if(a.at(x) == '1')
				rs += pow(2,exp);
			--exp;
		}


		cout << '\n' << "Jump Target: " << jmp;
	}
}



int main() { 

	cout << '\n' << "64 bytes from .bin file: " << '\n';

	const int SIZE = 64; // File size is 64 bytes
	char d[SIZE];

	readArray(d, SIZE);

	int counter2 = 0;

	// Print out the binary code for all instructions and compare them to 
	// the "Hexdump" of the file to make sure everything is right.
	for(auto i: d) {
		printBinary(i);
		cout << " ";
		counter2++;
		if(counter2%4 == 0)
			cout << '\n';
	}

	vector<string> s = {};

    for(auto i: d) {
    	s.push_back(printBinary2(i));
    	}

	string ins1  = s.at(0)  + s.at(1)  + s.at(2)  + s.at(3);
	string ins2  = s.at(4)  + s.at(5)  + s.at(6)  + s.at(7);
	string ins3  = s.at(8)  + s.at(9)  + s.at(10) + s.at(11);
	string ins4  = s.at(12) + s.at(13) + s.at(14) + s.at(15);
	string ins5  = s.at(16) + s.at(17) + s.at(18) + s.at(19);
	string ins6  = s.at(20) + s.at(21) + s.at(22) + s.at(23);
	string ins7  = s.at(24) + s.at(25) + s.at(26) + s.at(27);
	string ins8  = s.at(28) + s.at(29) + s.at(30) + s.at(31);
	string ins9  = s.at(32) + s.at(33) + s.at(34) + s.at(35);
	string ins10 = s.at(36) + s.at(37) + s.at(38) + s.at(39);
	string ins11 = s.at(40) + s.at(41) + s.at(42) + s.at(43);
	string ins12 = s.at(44) + s.at(45) + s.at(46) + s.at(47);
	string ins13 = s.at(48) + s.at(49) + s.at(50) + s.at(51);

	vector<string> instructions = {ins1, ins2, ins3, ins4, ins5, ins6,
	ins7, ins8, ins9, ins10, ins11, ins12, ins13};
	
	for(int x = 0; x < 13; x++)
	{
		cout << '\n' << "Instruction #" << x+1 << ": "
		     << instructions.at(x) << "\n";
		whatAreYou(instructions.at(x));
		cout << '\n';
	}
	
	return 0;
}