In this assignment you’ll write a C/C++ program to decode MIPS machine code. You don’t need to fully disassemble it (unless you want to!), but you do need to output, for each instruction,
The instruction format: R, I, or J
The opcode
The Rs, Rt, and Rd register numbers (not all instruction formats use all three registers)
The immediate value, if any
The jump address, if any
You can download a sample MIPS machine program here, or
find it on the server in /usr/local/class/cs241/mips-test.bin. This is a
binary file consisting of 13 MIPS instructions (i.e., 64 bytes long, including padding). You
should decode each instruction, and print the above information for each.
The main difficulties in implementing this in C++ are:
You need to read 32-bits (dword) from the input file as binary, not text.
MIPS is big endian as opposed to Intel which is little endian. This means that the bytes of the dword will be in reverse order when you first read them in.
To read from the input file in binary, you can use a loop like this:
istream in("..."); // Input filename
uint32_t instruction; // Most recent instruction
char buffer[4]; // Input buffer
// Read 4 bytes at a time
while(in.read(buffer, 4)) {
// Swap byte order
std::swap(buffer[0], buffer[3]);
std::swap(buffer[1], buffer[2]);
// Copy to instruction
std::memcpy(&instruction, buffer, 4);
// Decode instruction...
// Your code here
}
If you want to go full disassembler, you can find a list of opcode mnemonics (names) here.
For reference and checking your work, here is the original MIPS assembly of
the file use to create mips-test.bin:
li $v0,4
syscall
li $v0,5
syscall
move $t0,$v0
addi $t0,$t0,10
li $v0,4
syscall
li $v0,1
add $a0,$t0,$0
syscall
li $v0,10
syscall
(The GNU assembler’s AT&T syntax uses different names for the registers than what we’ve been using.)