CS152 Computer Architecture and Engineering

Lab #1: MIPS & Broken SPIM

Spring 2004, Prof John Kubiatowicz

Homework 1 due Monday 2/2 in class.  Please include the TIME or TA NAME of the DISCUSSION section that you attend as well as your NAME and STUDENT ID. Homeworks and labs will be handed back in discussion sections.  There will be a exam on the day that this is due.

Homework Policy: Homework assignments are due in class. No late homeworks will be accepted. There will be a short quiz in lecture the day the assignment is due; the quiz will be based on the homework. Study groups are encouraged, but what you turn in must be your own work.

Lab 1 is due Wednesday 2/4.  Be prepared to explain your debugging techniques to your TA during section.  Your lab report must be submitted by 11:59pm (Wednesday night) using the submit program (see below).
This lab is to be done individually.  It is rather long, so get started early!!!
Lab Policy: Labs (including final reports) must be submitted by 11:59pm on the day that the lab is due.. To Submit your lab report, run m:\bin\submit.exe or at command prompt, type "submit" then follow the instructions. Make sure you input the correct section number,  group name (for lab 3 ~5, and final project), and directory to submit. Otherwise your lab/project grade will NOT be correctly recorded. The required format for lab reports is shown on the handouts page.


Homework #1:

Please do the following problems from P&H: 1.51-1.53, 2.3, 2.15, 2.16, 2.18, 2.24, 2.32, 2.41, 2.44, B.15, B.21, B.22


Lab #1:

This is a demanding assignment - get started early!

The software for this assignment is located in m:\bin and m:\lab1. The broken version of spim is called spim_broken. The good version is called spim.

Problem 1: Introduction to SPIM

This problem will give you a chance to get familiar with SPIM, a MIPS simulator, the MIPS instruction set, and the calling convention. You will learn SPIM's basic functionalities by simulating a MIPS assembly program at calculates the factorial of 5. You should read chapter 3 and appendix A of P&H to prepare for this assignment. An on-line manual for SPIM can be found off the handouts web-page. Copy m:\lab1\fact.sto your home directory for this assignment. This program uses recursion to evaluate the factorial of 5 (f(N) = N * f (N - 1), f (0) = 1).

Type spim (or m:\bin\spim) to start the windows version of the SPIM program. Load the assembly program fact.s by pressing the open button, typing the file name in the dialogue box, and clicking on 'open'. Observe that the instructions for your main program now appear in the Text Segments pane (Hint: you can go to the "Windows" drop down menu to select which pane you want to display). You are using the default mode of SPIM which supports the extended instruction set and has no delayed jumps or delayed loads.

1a) The program does not look exactly the same as in the fact.s file, because the some of the instructions are macros and SPIM translates them to bare machine instructions. However, the original codes are displayed as comments. What do the instructions "li" and "la" mean? How are they translated to bare machine instructions? Turn-in an annotated version of fact.s that shows how the "virtual machine" instructions are expanded or translated into native instructions.

1b) What is the starting address of the 'main' routine? of 'fact'? Single-step the code from start until it reaches the first instruction of 'main'. Note that R31 has been modified. Which is the instruction that modified R31? What is the purpose of doing this?

1c) Set a breakpoint at the first instruction of the 'fact' routine. Continue tracing through the program execution by using single stepping and breakpoints. What are the registers sp and fp used for? Draw the values on the stack when the first instruction of the fact procedure is about to be executed for the fourth time.

1d) Without changing the logic of the program, improve the assembly language version by eliminating unnecessary data movement and changing registers accordingly. Turn in your improved program. Save your simulation to a log file from "File->Save Log File". Edit it to show a transcript of the key stages in the program with some comments on which values matter. (Please try to keep it short.)

1e) Convert your fact program to use a simple loop, rather than recursion, to compute the factorial. Show that it works.

1f) Now it is time to switch from the virtual machine to the bare hardware. To run the bare machine, check the "bare machine" option in "Simulator->Settings". Then restart spim. This turns off the assembly language translations and imposes delayed jumps (and branches) as well as delayed loads. Convert fact.s to use only the bare machine by translating the non-native instructions and by inserting NOPs after the jumps, branches, and loads. (You will need to convert the call in main to fact back into a simple JAL.) Turn in this version along with verification that it works.

1g) Eliminate as many NOPS as possible by moving instructions around the branch or load, while retaining the logic of the program. Your goal is to optimize your program as much as possible. Turn in the improved (working) version with an explanation of the changes and verification.

Problem 2: MIPS assembly programming

2a) Write a procedure, itoa, in MIPS assembly language that will convert an integer argument into an ASCII decimal string. The procedure should take two arguments: The first is an integer in register $a0; the second is the address at which to write a result string in register $a1.Then itoashould convert its first argument to a null-terminated decimal ASCII string and store that string at the given result location. The return value from itoa, in register $v0, should be a count of the number of non-null characters stored at the destination. Test your answer for the itoa() procedure on spim.  Now, write a main() procedure that generates an ASCII string for each of the first 100 integers and prints them to the console (using your itoa procedure, of course!).  Page A-48 (system-calls) from the book discusses how to print strings to the console.  Turn in a transcript of the results.

2b) Write and test a MIPS assembly language program to compute and print the first 100 prime numbers. A number n is prime if no numbers except 1 and n divide it evenly. You should implement two routines:

Test your program on spim.  Make sure to adhere to all MIPS calling conventions.  Print all primes on the console.  Turn in your code, as well as a transcript of the results. [hint: test each integer, starting at 2, for primality.  Keep in mind that a number is prime if it has no factors (2, 3, 5, 7, 11, ...).  A factor of a number X is any number which evenly divides it (without remainder).  For each X, you can get by with checking all possible factors Y with Y * Y < X (why?).]

2c) Several assembly language instruction are expanded into a short sequence of machines instructions by the assembler. Show the expansions that would be used for the following instructions described in Appendix A: abs, mul, mulo, neg, rem, rol, li, sgt, bgeu, bgt, ulw.

Problem 3: Writing diagnostic programs

Now we get to the hard part! You are given a buggy version of SPIM, called spim_broken (m:\bin\spim). It has 5 bugs in it. Your task is to write a set of diagnostic programs to isolate the bugs. (You will verify lots of other things work. Turn this in too.) You will need to work with the bare machine for this.

Here is a list of things you should check for:

  1. Register zero always has the value zero.
  2. All the branch and jump instructions should jump to the right address under the right condition.
  3. All the branch and jump instructions with link should put the correct return address into the right register.
  4. SLT(I) and STLU(I) must work properly with bit patterns representing negative two's complement integers or large natural numbers.
  5. All the arithmetic and logical instructions with immediate field should extend it properly.
  6. Make sure a load that follows a store to the same address reads the appropriate data.
  7. The correct endianess should be used on data transfer instructions.
  8. Jump and branch instruction should have a delay slot.
  9. Overflow should be detected correctly in arithmetic and logical instructions.
  10. Shifting instructions work correctly and extend the MSB appropriately.
You should make sure that the fundamental things work before you test some other things that depend on them. Once you have verified that simple compares and branches work, you can build longer programs with a sequence of tests. After each test, you can use a compare followed by a branch to either go to the next test, or to a "failure label" which will put in an identifier for the failed test in a register. As long as there are no failures, it will sequence through all the tests. You can easily look at the "failure register" at the end of execution to determine which (if any) of the tests failed. Your test code should look something like the following:

test case a
beq caseA_result, expected_Result, go_to_caseB
jump to failure A

caseB:
test case b
...
...

failure A:
addiu $t0, $0, 1
j endOfTest

failure B:
addiu $t0, $0, 2
j endOfTest

...
...
endOfTest:

Writing diagnostic programs can deepen your understanding of the instruction sets. The main purpose of this assignment, however, is not only to learn MIPS and understand the diagnostic process, but to teach you how to create programs that can be used to validate your design later in the semester. Since the final project only requires you to implement only a subset of the MIPS instruction set, the diagnostic programs in this assignment will only be useful later in the semester if they are written using this limited set of instructions. Hence, you must write the diagnostics using only the MIPS instructions below:

arithmetic: addu, subu, addiu
logical: and, or, xor, andi, ori, xori, lui
shift: sll, sra, srl
compare: slt, slti, sltu, sltiu
control: beq, bne, j, jr, jal
data transfer: lw, sw

Turn in a description of the specific errors that you found, the test code that excited the errors. Make sure to give a complete description of your testing strategy (methodology).  We expect you to describe your testing methodology carefully and give us a notion of how systematic it was and why you were able to detect the bugs that you did.  We are looking for an actual methodology here, including tests that didn't find bugs. Be systematic!