CPSC220: Introduction to Computer Architecture (Fall 2014)

Lab #4

Due before you leave for break on Friday, 10/10/2014

This assignment should be done in groups of two. Groups are free to discuss their ideas with other, but not to copy each others' code.

MIPS Disassembler

One of the central ideas that we've encountered in our study of the MIPS ISA is that assembly language—by virtue of being human-readable—provides an interface between the human programmer and the physical machine. Of course, a high-level language such as Java does this, too, but assembly languages offer a much tighter correspondence to an ISA.

On Wednesday, we engaged in some intense practice in decoding the instructions in a MIPS program by hand. In this assignment, you'll automate that decoding by writing a disassembler. Now a full-blast disassembler is an unpleasant proposition, with a lot of distraction from the real problem, namely decoding of MIPS instructions.

Your Job

Write a program that reads the machine instructions from the text section of a MIPS program and prints out the corresponding assembly-language program.

Note that the full instruction set is a lot to tackle, and resolving things like label targets is extremely difficult without writing your own linker. Getting the .data segment right would be completely overwhelming. Don't worry about those things! All you need to do is read the strings of "bits" (really, just 32-character strings, one per line), and decode them, with things like labels left as integers. Do not worry about the .data section nor the globals section. (You can produce test files from your MIPS programs by dumping to the "Binary text" format).

Also, if you can't do the entire MIPS instruction set, that's okay. Just get a reasonable subset done, roughly the instructions that we've actually used in our own examples. If you can get farther than that, terrific, but I don't expect it.

Here's a skeleton program, which takes care of the reading part (assuming input is from System.in). If you use this, you only job is to complete demipsify.


import java.util.ArrayList;
import java.util.Scanner;

public class DeMIPSify {
  public static void main(String[] args){
    
    ArrayList<Integer> instructions = new ArrayList<>();
    Scanner inp = new Scanner(System.in);
   
    int line = 0; // for debugging, in case there's bad input;
    
    try {
      String bits = "";  
      // Input format is a string of 32 0/1 characters, representing 
      // a single, 32-bit word.
      int nextInstr = 0;
      // For each line of input (representing an instruction), this will 
      // be the corresponding int
      
      while (inp.hasNext()) { // will be -1 when the input stream closes
        line += 1;  
        bits = inp.nextLine();
        nextInstr = Integer.parseInt(bits, 2);
        
        instructions.add(nextInstr);
      } // while
    } catch (NumberFormatException e) {
      System.err.println("Bad input on line " + line + ".  Bailing out.");
      System.exit(1);
    }
    
    String mipsProgr = "";
    
    for (Integer instr:instructions) {
      mipsProgr = mipsProgr + demispify(instr.intValue()) + "\n";
    }
    
    System.out.println(mipsProgr);
  } // main
  
  public static String demispify(int i) {
    return "MIPS instruction " + i;
  }
   
}

Final word: this is easier than it looks. You can extract a subset of the bits in an integer by using the & (bitwise and), | (bitwise or), << (unsigned left shift), and >>> (unsigned right shift). Bitwise and can be used to mask off bits (for example, " x & 0xFF" masks off all but the bottom 8 bits). The shift operators can move the bits you need to the left or right side. And so on.

Turn in:

To hand in your files: