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:
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:
Most operations are binary. When the "+" operation is done, the stack
should look like:
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:
- "-"
- Subtract. When completed, the stack should look like:
- "*"
- Multiply. When completed, the stack should look like:
- "/"
- Divide. When completed, the stack should look like:
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:
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:
- "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
]

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