Homework 7

22C:18, Summer 1997

Due Thursday, July 24

Douglas W. Jones

In lectures 29 and 30, the only macros actually defined for manipulating the stack were add, pushimm and select. In practice, you'd probably like others! Consider the following list of macros:

pushvar x
push the variable named x; assume that x is declared the way it is in the local and global macros from highlevel.h.

popvar x
push the variable named x; assume that x is declared the way it is in the local and global macros from highlevel.h.

pushaddr x
push the address of a variable named x; assume that x is declared the way it is in the local and global macros from highlevel.h.

get
push( M[pop()] ) -- follow a pointer on the stack top.

put
M[pop2()] = pop1() -- follow a pointer for store.

sub
push( pop2() - pop1() ) -- subtract.

neg
push( - pop() ) -- negate the stack top.

ls
push( pop2() << pop1() ) -- left shift.

ars
push( pop2() >> pop1() ) -- signed (arithmetic) right shift.

urs
push( pop2() >> pop1() ) -- unsigned right shift.

eq, gt, lt, ge, le, ne
push( pop2() = pop1() ) -- compare for equality.
push( pop2() ? pop1() ) -- the others are similar!
The following questions assume the use of these macros:
  1. Convert each of the following to a string of calls to the above macros:
    	a = b - (c << 2);
    
    	b = a[ i ];  -- assume i is an array of integers
    
    	a[ i ] = i + 5;  -- assume i is an array of integers
    
  2. Write code for the ars macro.

  3. Write code for the if, else and endif macros. These should allow you to rewrite
    	if (i > 5) xxxx; else yyyy;
    	
    as the following:
    	pushvar i
    	pushvar 5
    	gt
    	if
    	  xxxx
    	else
    	  yyyy
    	endif
    	
    Your macros should follow the same scheme used for the loop macros in lecture 30.

  4. Consider the select/case given in lecture 30. Here is a small bit of C code:
    	select (i) {
    	  case 0: xxxx; break;
    	  case 1: yyyy; break;
    	  otherwise zzzz; break;
    	}
    	
    This can be written using our macros as:
    	pushvar i
    	select
    	  case 0
    	    xxxx
    	    break
    	  case 1
                yyyy
    	    break
    	  otherwise
    	    zzzz
    	    break
            endselect
    	
    Show the result of expanding these macros, so that the code is pure SMAL Hawk assembly language, with no macros other than the basic macros for Hawk machine instructions given in the hawk.macs file. You can get some help by actually typing this in and assembling it, but you'll find that the best way to solve this problem is to actually hand-expand the macros.

  5. In the notes on the select/case macros, it noted that these macros differ from the C (and C++) select/case statements in one significant way. Can you find it? (and what is it?)