Homework 6

22C:18, Fall 1996

Due Tuesday Oct. 15, 1996 in discussion

Douglas W. Jones
  1. 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.)

  2. 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.

  3. 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.

  4. 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!