Problem Set 0: An introduction to ML and MIPS
Due Wednesday, 23 Jan 2013, 11:59pm
The goal of this problem set is to expose you to programming in ML and to learn a few details of the MIPS instruction set architecture.
Instructions: We have provided skeleton code which you can find here. Your job is to fill in the parts of the skeleton code marked TODO. To submit your work, create a zip archive containing all of the files provided in the original skeleton code distribution. Please name the zip archive ps0-lastname1-lastname2, where lastname is replaced with your own. We encourage you to work with a partner (there is a lot of code here). If the zip archive does not compile with make, then they will not be accepted. If you run out of time, it's better to comment out the parts that aren't working than to submit something that won't compile. Submit your assignment by emailing the zip archive to 4410staff at ccs.neu.edu. (Pay attention to the piazza forum for any announcements on a change in submission process.)
There are two parts to this assignment. The first part consists of writing a MIPS assembler. In the second part, you will implement an interpreter for a subset of the MIPS instruction set.
Part 1: MIPS AssemblerIn this part, you will build an assembler for a subset of MIPS assembly. The assembler translates assembly code into machine code, the code that runs on hardware. This exercise will demonstrate how we get from assembly code, something that is still somewhat human-readable, to machine code. To do this part of the assignment, you will need to understand how MIPS assembly is encoded at the level of bits. To this end, the MIPS documentation is your friend. You can find information about how to encode instructions (and their semantics) in chapter A.10.2 (starting with page A-49) of the SPIM Simulator chapter. Your job is to write the assem function in mips_sim.ml.
let rec assem (prog : program) : stateAt a high level, you will transform a list of assembly instructions, a program, into an intial starting state. A state consists of a register file, memory and program counter. Refer to the skeleton code for more information.
Part 2: MIPS InterpreterIn this part, you will build an interpreter for MIPS code, similar to the SPIM simulator. The goal of this exercise is to become more familiar with the MIPS instruction set architecture and to gain more experience writing ML code. The interpreter is structured as a function:
let rec interp (init_state : state) : stateYour job is to write the interp function which simulates one step of execution at a time until program termination (for the purposes of this assignment, treat the 0x00000000 as the program termination "instruction"). During a step, you should fetch a word's worth (4 bytes) of values from memory, starting at the address given by the program counter. (It doesn't matter which Endian-ness you pick, but be consistent.)
You should then decode the instruction and perform the associated operation. For example, if the instruction bytes decode to an "add $1,$2,$3", then you should update register one, with the sum of the values in registers two and three, and update the program counter so that it points to the next instruction. Look closely at the Int32 module Ocaml standard library as it provides most of the functions that you will need for doing bit manipulation.
Important!! Note that the load immediate (li) instruction is a pseudoinstruction. This means that its ok to use it in a Mips assembly program, with the caveat that Mips hardware does not actually support this instruction. Instead, the hardware supports a li instruction by encoding it as two instructions, a lui and ori. Thus, your assembler should accept any Mips assembly program that contains a li instruction, but your interp function should only accept lui and ori instructions to model the Mips hardware.