I am working on a project for a Computer Architecture class, where we are learning about MIPS and assembly language. I am to take a binary MIPS executable file that looks like this:
00000000010000000000000000000000
00010000000000010000000000000000
01111111111111111110111111111100
00000000000000000000000000000011
00000000000000000000000000000001
00000000000000000000000000000010
00000000000000000000000000000011
00111100000000010001000000000001
00110100001010000000000000000000
00100100000010010000000000000011
00100100000010100000000000000000
00010001010010010000000000000110
10001101000010110000000000000000
00100011101111011111111111111100
10101111101010110000000000000000
00100001000010000000000000000100
00100001010010100000000000000001
00001000000100000000000000000100
00111100000000010001000000000001
00110100001010000000000000000000
00100100000011000000010011010010
10101101000011000000000000000100
00100100000000100000000000001010
00000000000000000000000000001100
And decode it to produce a human readable assembly language .txt file that looks like this:
initialPC: 4194304
dataStartAddress: 268500992
initialStackPointer: 2147479548
Number of data items: 3
268500992: 00000000000000000000000000000001 1
268500996: 00000000000000000000000000000010 2
268501000: 00000000000000000000000000000011 3
4194304: 00111100000000010001000000000001 lui $at, 4097
4194308: 00110100001010000000000000000000 ori $t0, $at, 0
4194312: 00100100000010010000000000000011 addiu $t1, $zero, 3
4194316: 00100100000010100000000000000000 addiu $t2, $zero, 0
4194320: 00010001010010010000000000000110 beq $t2, $t1, 6
4194324: 10001101000010110000000000000000 lw $t3, 0($t0)
4194328: 00100011101111011111111111111100 addi $sp, $sp, -4
4194332: 10101111101010110000000000000000 sw $t3, 0($sp)
4194336: 00100001000010000000000000000100 addi $t0, $t0, 4
4194340: 00100001010010100000000000000001 addi $t2, $t2, 1
4194344: 00001000000100000000000000000100 j 4194320
4194348: 00111100000000010001000000000001 lui $at, 4097
4194352: 00110100001010000000000000000000 ori $t0, $at, 0
4194356: 00100100000011000000010011010010 addiu $t4, $zero, 1234
4194360: 10101101000011000000000000000100 sw $t4, 4($t0)
4194364: 00100100000000100000000000001010 addiu $v0, $zero, 10
4194368: 00000000000000000000000000001100 syscall
Since the binary file is dumped into a binary text file, I successfully created a program that converts the .txt to a .bin that passes a diff with the .bin my instructor included in the project materials with help from this community in a previous ask.
Currently I am running an issue of printing the words correctly. Here is the output file of my program currently:
initialPC: 16384
dataStartAddress: 272
initialStackPointer: 4243586943
Number of data items: 50331648
16777216
33554432
50331648
17826108
10292
50333988
2596
100682001
2957
4244618531
43951
67110945
16796193
67112968
17826108
10292
3523480612
67112109
167772708
201326592
Obviously I am doing something wrong here, so I would love some help explaining what I did wrong and how to correct it. My instructor is just expecting us to create this entire program using AI, and I don't jive with that. Going the long route may mean more work on my end, but I'm going to school to learn how to code, not create prompts.
Here is my code as of the moment:
#include
#include
#include
using namespace std;
int main(int argc, char* argv[])
{
//input error check the proper amount of command arguements
if (argc != 3) {
cerr << "Usage: " << argv[0] << " input.bin output.txt\n"; //cerr is used for unbuffered error messages
return 1;
}
//open input and output streams, check they open properly
ifstream in;
in.open(argv[1], ios::binary);//reading in binary mode
if (!in.is_open())
throw runtime_error("Error opening input file");
ofstream out;
out.open(argv[2]);
if (!out.is_open())
throw runtime_error("Error opening output file");
uint word = 0;
int count = 0;
while (in.read(reinterpret_cast(&word), 4)) { //read 32 bits (4 bytes) at a time
switch (count)
{
case 0:
out << "initialPC: " << word << endl;
break;
case 1:
out << "dataStartAddress: " << word << endl;
break;
case 2:
out << "initialStackPointer: " << word << endl;
break;
case 3:
out << "Number of data items: " << word << endl;
break;
default:
out << word << endl;
break;
}
count++;
}
//close streams
in.close();
out.close();
return 0;
}
Coded in VSC, compiled with GCC and run through WSL. Here are the resources that I've been using to help me understand how to read from and write to binary files, but they don't say anything about what to do with the data after it's read:
https://cplusplus.com/doc/tutorial/files/
https://www.eecs.umich.edu/courses/eecs380/HANDOUTS/cppBinaryFileIO-2.html
So the 2 biggest questions I would love answered:
1.) How do I properly read each 32 bit unsigned int from the file and print to the file? Would it be easier to read them into an uint array so that I can freely access them? (I feel that will be helpful when decoding the binary for each line to get the assembly instruction, and there is a second section of this project where I am to simulate the commands). I believe endianess will need to be reversed.
2.) How do I convert the decimal integers back into binary, for the lines after the first 4? Ignore the assembly decoding.