MC28 Lab 2: SLIM Assembly Language Programming (Fall 1996)
Due: October 16, 1996
Introduction
For this lab, you will do some SLIM assembly language programming
exercises from chapter 11 of our book. For certain of these
exercises, you are asked to gather statistics from the SLIM simulator
in order to determine the relative efficiency of various versions of
the same problem. You will also have the opportunity to see
how the execution of a SLIM program progresses (how the registers and
memory change in contents, the PC steps, etc.), because the SLIM
simulator we will be using provides a visual display of the
execution. (The simulator is called SLIME, the SLIM Emulator.)
You will work on this lab as a member or a twoperson (or if need be,
threeperson) team. Each team is to submit a single jointlyauthored
lab report.
SLIME
The SLIM assembly language programs need to be written a little bit
differently for SLIME than the way they are shown in the book. The
differences are best illustrated by an example; this is what you'd put
in a file to load into SLIME for the iterative factorial program from
the book:
allocateregisters a, b, one, factorialproduct, end
li a, 1
read b
li one, 1
li factorialproduct, factorialproductlabel
li end, endlabel
factorialproductlabel:
;; computes a * b! into a and then jumps to end
;; provided that b is a nonnegative integer;
;; assumes that the register named one contains 1 and
;; the factorialproduct register contains this address;
;; may also change the b register's contents
jeqz b, end ; if b = 0, a * b! is already in a
mul a, a, b ; otherwise, we can put a * b into a
sub b, b, one ; and b  1 into b, and start the
j factorialproduct ; iteration over
endlabel:
write a
halt
The differences illustrated in the above example are as follows:

There are no parentheses, no quote mark, no
preprocessorassemble
or define
around the
outside.

The operands in each instruction (and names in the
allocateregisters
line) can be separated by commas as
shown above, though that isn't required.

The labels need to be followed by colons, though only where they are
being used to label an instruction, not where they appear as an
operand in an
li
instruction.
You will need to put each SLIM program in a separate file. You can
use SchematiX for this, but any other text editor would also work.
You then will run SLIME as a separate program, as described below. It
has a ``load'' button that pops up a file selection panel, in which
you would select the SLIM program you want to load in. You would then
use other features of SLIM to run the program and observe its
execution.
To actually run SLIME on an SGI, the most easy approach would be to
first put the SLIME icon on your desktop, and then whenever you wanted
to run it, you could just double click it. To get the icon, you can
use the ``Find Icon'' feature of the SGI's ``toolchest'' (the menu
usually displayed in the upper left of the screen), and then in the
panel that presents type in ~max/MC28/SLIME
and drag the
resulting icon onto your desktop.
As with most activities involving the mouse, this is easier shown than
described. The lab section will only have three groups in it, so
David should be able to get you past these hurdles.
Getting acquainted
The next thing to do once you have SLIME running is to try it out on
some simple programs from the book, maybe starting with the one that
just writes out 314. The key thing to know is that you can not only
run the program full speed ahead by pressing the start button, but can
also step through it one instruction at a time using the step button.
This is very helpful for seeing what is happening. The highlighted
line in the instruction panel is always the instruction that is about
to be executed, not the one that was just executed.
Programming exercises
Note that the postlab section, below, asks you to analyze some
instruction count data, so you will have to gather the data for that
in lab as well as doing the programming (and testing and debugging).
The exercises you should do are as follows:

Exercise 11.2 on page 362.

Exercise 11.4 on page 370. On page 73, the program which performs
exponentiation uses powerproduct:
(define powerproduct
(lambda (a b e) ; returns a times b to the e power
(if (= e 0)
a
(powerproduct (* a b) b ( e 1)))))

Exercise 11.5 on page 370. Note that a large result such as (power
3 50) may result in an overflow. Feel free to ignore the overflows
when counting instructions, but briefly discuss the effects (if any)
this might have on your conclusions.

Exercise 11.9 on page 376.

Exercise 11.10 on page 381. As you might expect, the recursive
power procedure looks like:
(define power
(lambda (base exponent)
(if (= exponent 0)
1
(* base
(power base ( exponent 1))))))
Postlab
Each group should write a single lab report, authored by all members
of the group. As usual, write up a lab report that explains all of
what you did to an audience generally knowledgeable about Scheme (and
also SLIM for this lab), but ignorant of specifically what you did.
You are asked to compare the efficiency of the three different
assembly language versions of power
in exercises 11.4, 11.5,
and 11.10. You should do this by comparing how many instructions the
three versions execute for various exponents. For example, you might
test each version with exponents 2, 4, 8, 16, and 32, and report your
results in a table. Or you could graph the results.
Note that the Scheme code from which the three versions are written
generate processes that are linearly iterative (11.4), logarithmically
iterative (11.5), and linearly recursive (11.10). Do your results
match these expectations? In the case of the linear versions, you
might expect the number of instructions to be a linear function of the
exponent n (that is, expressible as An +
B for some values of A and B). Can
you find such a pair of A and B for each of the
iterative versions? How do the values of A and
B for one version compare with the values of A
and B for the other version? How could you check that the
process generated by your program from exercise 11.5 has logarithmic
growth?
If you have more time
In the postlab section, we suggested making measurements with
exponents of 2, 4, 8, 16, and 32, all of which are powers of two. If
you use exponents that aren't powers of two, then the analysis of the
program from exercise 11.5 becomes more interesting. Suppose you
write a number n in binary; for example 13 would be written
as 1101 because it is 1*2^{3} + 1*2^{2} +
0*2^{1} + 1*2^{0}, i.e., 8+4+1. Let
a(n) be the number of zeros in this binary
numeral (without any extra leading zeros tacked on at the left end),
so that for example a(13)=1, and let
b(n) be the number of ones in the binary
numeral, so for example b(13)=3. Can you make a
predication regarding how the number of instructions executed by the
program from exercise 11.5 can be computed as a function of
a(n) and b(n), where
n is the exponent? Try experimentally verifying your
prediction.
Course web site: http://www.gac.edu/~max/MC28
Instructor: Max Hailperin <max@gac.edu>
Lab instructor: David Wolfe <wolfe@gac.edu>