Consider the following (bad) idea:
- Set aside R1-2 as short-term temporaries
- Set asider R3 as the frame pointer
- Set aside R4 as the stack pointer
This would allow us to write macros such as the following
(note the use of lower case to avoid conflict with predefined
Hawk symbols):
MACRO add
ADDSI R4,-4
LOADS R1,R4
LOAD R2,R4,-4
STORE R2,R4,-4
ENDMAC
MACRO pushimm =c
LIL R1,c
STORES R1,R4
ADDSI R4,-4
ENDMAC
Using the above macros as style guidelines, write out enough macros based on
the B5000 instruction set that you can test the following function, based on
the code presented in lecture 28:
function multiply
; assume the caller the parameters above the mark
; x is therefore local variable 0
; y is therefore local variable 1
pushlocal 0 ; get x
bne else ; see if it's nonzero
pushimm 0
funcreturn
else:
pushmark ; setup to push parameters to call
pushlocal 1 ; get y
pushlocal 0 ; get x
pushimm 1
sub ; we're passing x-1
paramcall multiply, 2
pushlocal 1 ; get y
add ; we're returning multiply(y,x-1)+y
funcreturn
Note that there are no Hawk instructions in the above function! Even the
bne instruction (note the use of lower case) is based on the B 5000
instruction -- it pops the stack top and tests the value popped, rather than
just testing a register.