1.3subroutine and Control Abstraction
1.3subroutine and Control Abstraction
Stack Layout,
Calling sequence,
parameter passing
Allocation strategies
– Static
Code
Globals
Own variables
Explicit constants (including strings, sets, other
aggregates)
Small scalars may be stored in the instructions themselves
Allocation strategies (2)
– Stack
• parameters
• local variables
• temporaries
• bookkeeping information – Heap
• dynamic allocation
•Contents of a stack frame
–bookkeeping
•return PC (dynamic link)
•saved registers
•line number
•saved display entries
•static link
–arguments and returns
–local variables
–temporaries
Calling Sequences
• Maintenance of stack is responsibility of calling sequence and subroutine prolog and epilog
will discuss in Chapter 3
– space is saved by putting as much in the prolog and epilog as possible
– time may be saved by putting stuff in the caller instead, where more information may be
known • e.g., there may be fewer registers IN USE at the point of call than are used
SOMEWHERE in the callee
• Common strategy is to divide registers into caller-saves and callee
-saves sets
– caller uses the "callee-saves" registers first
– "caller-saves" registers if necessary
• Local variables and arguments are assigned fixed OFFSETS from the stack pointer or frame
pointer at compile time
– some storage layouts use a separate arguments pointer
Parameter Passing
• Parameter passing mechanisms have four basic implementations
– value
– value/result (copying)
– reference (aliasing)
– closure/name
• Many languages (e.g. Ada, C++, Swift) provide value and reference directly
C/C++: functions
– parameters passed by value (C)
– parameters passed by reference can be simulated with pointers (C)
void proc(int* x,int y){*x = *x+y }
…
proc(&a,b);
– or directly passed by reference (C++)
void proc(int& x, int y) {x = x + y } proc(a,b);
Ada goes for semantics:
who can do what
– In: callee reads only
– Out: callee writes and can then read (formal not initialized); actual modified – In out: callee reads and
writes; actual modified
• Ada in/out is always implemented as
– value/result for scalars, and either
– value/result or reference for structured objects
• In a language with a reference model of variables (ML, Ruby), pass by reference (sharing) is the obvious
approach
• It's also the only option in Fortran
• If you pass a constant, the compiler creates a temporary location to hold it • If you modify the temporary, who
cares?
• Call-by name is an old Algol technique
• Think of it as call by textual substitution (procedure with all name parameters works like macro)
- what you pass are hidden procedures called THUNKS