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