CSE 30 -- Lecture 10 -- Oct 29


In this lecture, I gave out assignment 4, due before class on Nov 10th:

Write a Reverse Polish Notation (RPN) calculator in the MIPS assembly language. It should, like the HP calculators, provide a 4-deep parameter stack: we name the stack locations x, y, z, and w, and draw it thus:

w
z
y
x
When the user types in a number in the SPIM console window (and hits carriage return), the new number (call it n) will cause the stack values to move, with a value falling off the end, so the stack should look like:
z
y
x
n
Most operations are binary. When the "+" operation is done, the stack should look like:
z
z
y
n + x
Suppose the stack contained x, y, z, and w as in the original picture. The calcuator must provide the following functions:
"+"
Add. When completed, the stack should look like:
w
w
z
x+y
"-"
Subtract. When completed, the stack should look like:
w
w
z
y-x
"*"
Multiply. When completed, the stack should look like:
w
w
z
y*x
"/"
Divide. When completed, the stack should look like:
w
w
z
y/x
Division by zero is an error and should generate a message; in this case, the stack should not be affected.
"^"
Exponentiate. When completed, the stack should look like:
w
w
z
yx
Exponentiation by a negative number is an error and should generate a message; in this case, the stack should not be affected.
"b"
Set current base. When completed, the stack should look like:
w
w
z
y
"p"
Print top of stack (x) in current base. No effect on stack.
"a"
Print all of stack, w first, then z, y and then x in the current base.
"o"
Turn calculator off. main should return 0.
Input of numbers must be in the current base. (Initially base 10.) Digits are encoded 0, ..., 9, A, B, ..., F, G, ..., Z for zero through thirty five . Digits whose value is larger than the current base is not allowed and should generate an error. An exception is made for A, so that "A" "b" can always be entered to reset the calculator to base 10. The maximum base is 36; minimum is 2.

You must use functions with the standard calling sequence / register usage convention to implement each of these calculator operations. Hint: don't get confused between numbers and repreentations of numbers. Your stack should hold numbers, and you convert to/from various bases (representations of numbers) only during I/O. You do not need to allow for entry of negative numbers, but the calculator must internally be able to handle negative numbers, and it should be able to print them out. You do not need to worry about overflows.

The code for printing and reading a number may be obtained from the sample solutions from last year's course. as that course's assignment 4 (lecture 8). The original C code is provided as well as the converted assembly. (They are not, strictly speaking, completely equivalent.) You cannot use this code directly, but you should be able to adapt this code to this assignment without too many problems.

You should design -- and probably get working -- a C version of this assignment before attempting to code this in MIPS assembler; that will make the assignment more tractable.

This is not an easy assignment, and I suggest that you start on it right away. I wrote it in 1 hour and a half (mostly typing in code and maybe 5 minutes of testing), and then added comments for another 20 minutes or so. You will require a significantly longer amount of time -- allocate several hours to debugging alone. There are approximate 280 lines of assembly code in my implementation, and 120 lines of comments (400 lines of text total). About 90 of these lines were adapted from the sample code.

Jump Tables

I went over an example of how to transate a C switch statement into a jump table. See Patterson & Hennessey, page 129-130 of Chapter 3.

The design decision of when to use a jump table rather than a sequence of tests depend on several factors: whether the cases are dense or sparse, and whether you want to make a speed/memory trade-off. With dense jump targets, usually a jump table makes sense, though there are some processors which have limited data memory but more code memory (some kinds of embedded applications where code is burned into ROM and code ROM is distinct from data memory [harvard arch], for example). When the cases are sparse, then you may need to use a large jump table, and then the performance gain versus memory tradeoff is not so obvious. (Another alternative is to find a fast hash function to hash into a smaller jump table, making the jump table smaller, but requiring the jump targets to verify that the switch index was actually correct.)

Note that you do not have to have a jump table in your code for this assignment, though you may of course put one in.


[ CSE home | CSE talks | bsy's home page | webster i/f | yahoo | lycos | altavista | pgp key svr | spam | commerce ]
picture of bsy

bsy@cse.ucsd.edu, last updated Thu Nov 6 19:37:31 PST 1997.

email bsy


Don't make me hand over my privacy keys!