CS 310 FAll 99 Handout #15 CCE-Y 10/25/99 Supporting Material on HW/SW support for modularity Featuring the CS 310 Fall 99 Stack Frama terms: leaf routine actual parameters vs formal parameters call by value vs call by reference local variables frame pointer activation record (or stack frame) callee-saved vs caller-saved registers --------------------------------------------------------------------------- 1. Format of the CS 310 Fall 99 Stack Frame: low memory addresses <------ stack pointer and frame ptr local variables callee-saved registers old copy of frame pointer return address (if this is NOT a leaf routine) actual parameters (no caller saved regs) high memory addresses and the function result will be returned in $3 --------------------------------------------------------------------------- 2. The rest of this handout is the definition of a function and it's caller and then is implemented using the CS 310 Fall 99 Stack Frame approach. Here is a description of a HLL function and some of the compiler strategies for using the stack. int function compute ( A, B ) (assume all params are integers passed by value; assume params passed right-to-left: and that the function has 2 local variables: X, Y integers, and that the compiler will only need to use two reg $22,$23 for temporary computations. (this is a callee save register) (assume the stack is used for all components of the activation record including the frame pointer, and access the fields of the record using the frame pointer) { int X, Y; ... # compute calls another function ... ... X = B; return (A + B); } main calls compute as follows: C=compute (D, E); --------------------------------------------------------------------------- IMPORTANT Note: per the book, the sp should always be at the first empty word above the top of the stack. --------------------------------------------------------------------------- a) Diagram the stack frame for compute (label each component and give the # of bytes for each) <------ stack pointer <------ frame pointer local variable X (4 bytes) X and Y can be in local variable Y (4 bytes) either order. saved $22 (4 bytes) $22 and $23 could have saved $23 (4 bytes) been reversed old frame pointer (4 bytes) return address (4 bytes) actual parameter D (value) (4 bytes) (i.e. formal parameter A) actual parameter E (value) (4 bytes) (i.e. formal parameter B) ---------------------------------------------------------------------------- b) then translate the HLL code below into the MIPS ISA: The code in main: # C = compute(D, E); lw $8, E # push E onto the stack sw $8, ($sp) sub $sp, $sp, 4 # or add -4 lw $8, D # push D onto the stack sw $8, ($sp) sub $sp, $sp, 4 jal compute # call compute sw $3, C # store function result -------------------------------------------------------------------------- c) then write the code inside the compute function # let's calculate helpful symbolic names for the offsets using equates: compute_sf = 32 # size of the complete stack frame is 32bytes compute_locals = 8 # size of locals is 8bytes X = 4 # offset from frame pointer Y = 8 R22 = 12 R23 = 16 OFP = 20 RA = 24 FparamA = 28 FparamB = 32 # function prologue compute: sw $31, ($sp) #push the return address #it's ok to call $31 the nickname of $ra sub $sp, $sp, 4 sw $fp, ($sp) #push the old frame pointer sub $sp, $sp, 4 sw $23, ($sp) #push the old copy of reg23 sub $sp, $sp, 4 sw $22, ($sp) #push the old copy of reg22 sub $sp, $sp, 4 sub $sp, $sp, compute_locals # need 8bytes for locals move $fp, $sp #initialize fp to bottom of # compute's stackframe # function body now follows ..... # assume much has been omitted from the function lw $23, FparamB($fp) # X = B sw $23, X($fp) lw $22, FparamA($fp) # return (A + B); add $3, $22, $23 # function epilogue # now it's time to clean up the stack inside compute.... # here's the most efficient approach to cleaning up the stack inside the # function (but it may not be the most intuitive...) # lw $22, R22($fp) # restore all saved registers lw $23, R23($fp) lw $31, RA($fp) lw $fp, OFP($fp) # NOTE, can't use fp anymore... # quick way to reset the $sp to get rid of the stack frame is add $sp, $sp, compute_sf jr $31 # now can return to main -------------------------------------------------------------------------- #end of program