-
Write appropriately commented SMAL Hawk assembly language equivalent to the
following C function, preserving as much as you possibly can of the control
structure of the original:
int fib(x)
int x;
{
if (x < 2) return x;
return fib(x - 1) + fib(x - 2);
}
(OK, I admit it, calling fib(n) is a horribly inefficient way to compute
the n'th Fibonacci number, but it does work, and it does demonstrate
recursion.)
-
An alternate convention for parameter passing, commonly used on many machines,
is to pass parameters on the stack. So, prior to calling a procedure, the
caller puts the parameters into place in the activation record for the
called procedure. Consider a procedure with two parameters and 3 local
variables (1 word each). The activation record for this procedure would
have the following structure:
----------------------
| Saved Return Address | 00 --Offset from R2
|----------------------|
| Parameter 1 | 04
|----------------------|
| Parameter 2 | 08
|----------------------|
| Local Variable 1 | 0C
|----------------------|
| Local Variable 2 | 10
|----------------------|
| Local Variable 3 | 14
----------------------
Rewrite your SMAL Hawk code for the fib procedure from problem 1 so that
it uses this approach to passing parameters.
-
In the notes for the Oct 9 lecture, the possibility of instructions called
CALL and RETURN was mentioned. While adding these to the Hawk machine would
not be reasonable, nothing prevents us from writing macros that have exactly
the syntax mentioned in the lecture notes and that, from the user's perspective
have exactly the same function as the suggested instructions. Write such
macros.
Hint: Since theres no PROC macro marking the entry point to the procedure,
the CALL macro has to store the return address in the activation record
prior to the transfer of control. You can use PC-relative addressing on the
LEA instruction to get this address.
-
Hawk byte addressing is a bit slow, while Hawk word addressing is fast.
Many other machines share this problem, to one extent or another. The
design of the Pascal programming language takes this into account with
arrays by allowing arrays to be declared as packed or (by default), unpacked.
A packed array of characters (or halfwords) stores elements consecutively
in memory, while an unpacked array stores one element per word, wasting
memory but allowing faster addressing. The language includes two standard
procedures, pack and unpack, that can be used to convert arrays between
these forms. At the assembly language level, packb(a,b,c) would take
a as a pointer to an unpacked array of bytes, b as a pointer to a packed
array of bytes, and c as a count of the number of array elements to
transfer from a to b. (In Pascal, the length was implicit, being an
attribute of the types of a and b.)
Write an assembly language version of the pack routine, emphasizing
documentation of the procedure linkage and clear readable code for
the procedure!