Title: Prepared by
1Subroutines
Programming Language Principles Lecture 24
- Prepared by
- Manuel E. Bermúdez, Ph.D.
- Associate Professor
- University of Florida
2Abstraction
- A process by which a programmer associates a name
with a potentially complicated program fragment. - Goal Think in terms of purpose vs.
implementation. - Two forms of abstraction
- Control Abstraction Represent an action.
- Data abstraction represent data (more later).
3Control Abstraction
- Main control abstraction mechanism the
subroutine. -
- Subroutines perform operations on behalf of the
caller. - Can accept parameters. Parameters influence the
subroutine's behavior. Give the subroutine data
on which to operate.
4Terminology
- Argument actual parameter.
- Parameters formal parameter.
- Subroutine that returns a value a
function. - Subroutine that doesn't return a value a
procedure. - Procedures are only executed for their side
effects.
5Subroutine Stack Layout
- Storage consumed by parameters can be allocated
on a stack. - Each routine that is called gets a stack
frame/activation record on top of the stack. - A frame contains
- Arguments, that are passed into the subroutine.
- Bookkeeping info (such as return address of
caller, saved registers). - Local variables / temporaries.
6Stack Layout (revisited)
7Frame Management
- Keeping the stack frame intact is the
responsibility of the calling sequence code
executed by the caller immediately before and
after a subroutine call. - Prologue Code executed at beginning (pass
parameters, save return address, change program
counter, change SP, save registers) - Epilogue Code executed at the end (restore SP,
restore registers, etc.) - Calling sequence varies from processor to
processor, and compiler to compiler.
8Frame Management
- When a subroutine is finished it pops its frame
from the stack (and leaves its return value if
there is one on top of the stack) - Stack pointer (SP) Register contains the address
of the first unused location at the top of the
stack. - Frame pointer (FP) Contains an address within
the frame. Objects within the stack are
referenced via displacement addressing with
respect to the FP.
9Static Links (revisited)
- In a language with nested subroutines and static
scoping (Pascal, Ada, Modula) objects that lie in
surrounding subroutines (neither local, nor
global) can be found by maintaining a static
chain. - Static Link (SL) Reference to (most recent
instance of) the frame of the lexically
surrounding subroutine. Needed to look up
non-local variables (in surrounding scope).
10Maintenance of static chains
- Standard approach
- caller computes callee's SL and passes it as an
extra hidden parameter. - Two cases
-
11Static Links (revisited)
- The callee is nested (directly) inside the
caller. The callee's static link should refer to
the caller's frame. The caller passes its own FP
as the callee's SL. - Example A calls E, or B calls D.
12Maintenance of static chains (contd)
- The callee is k gt 0 scopes outward -- closer to
the outer level of lexical nesting. All scopes
that surround the callee also surround the
caller. The caller dereferences its own SL k
times and passes the result as the callee's SL. - Example E calls B, D calls C, or C calls B.
13Static Link Disadvantage
- An object in a scope k levels out requires
dereferencing the chain k times. - We can fix this by using a display.
- A display embeds a static chain into an array.
- The j-th element of the display contains a
reference to the frame of the most recently
active routine at nesting level j.
14Maintenance of Displays
- When calling subroutine at level j, the callee
saves the current value of the jth display into
the stack and replaces it with a copy of its own
FP. - Two cases
15Maintenance of Displays (Case 1)
The callee is nested (directly) inside the
caller. Caller and callee share all display elems
up to the current level. Put callee's FP into
the display. Example A calls E, B calls D.
16Maintenance of Displays (Case 2)
- The callee is at nesting level j, k gt 0 scopes
outward from the caller. Caller and callee share
display up to j-1. The caller's entry at j is
different, so callee must save it before storing
its own FP. - Example E calls B, D calls E.
17Handling Closures
- If callee is called through closure, the display
scheme breaks. - Solved by storing the entire display in the
callees frame. - Expensive, and not always necessary to store the
entire display. - Good argument for using static links. In general
maintaining display is more expensive than SL.
18Efficiency (Static link vs. Display)
- Display in memory a non-local object can be
loaded in memory with two memory access
operations. One for display, one for object
loading. - Static links non-local loading requires k
dereferencing operations. - Most programs don't nest subroutines more than
2/3 levels deep. So static chain is short.
19Efficiency (Static link vs. Display)
- Maintaining display is more expensive then
maintaining static chain. - Static chains allow closures (subroutines passed
as parameters). - Display (typically) uses fixed size array.
Imposes a maximum depth of nested subroutines.
20Case study 1
- C (gcc v. 2.7.2) on MIPS architecture (RISC)
- For description of MIPS architecture, see Section
5.5.1 of the textbook. - Arguments are accessed via offset from fp.
- First four scalar arguments are passed through
registers (r4-r7, or f12-f15)
21gcc on MIPS Architecture
22 gcc on MIPS Architecture (contd)
- The caller
- Saves any caller-saved registers that are still
needed. - Puts up to four scalar arguments into the
registers. - Puts remaining arguments at top of current frame.
- Performs a JAL (jump) which puts the return
address in register ra and jumps to the target.
23gcc on MIPS Architecture (contd)
- In the prologue the callee
- Subtracts the frame size from the sp.
- Saves any necessary registers into the beginning
of the new frame, using sp as base for
displacement mode addressing. - copies sp into fp.
24gcc on MIPS Architecture (contd)
- In the epilogue the callee
- Places return value (if any) into r2, f0 or
memory. - Copies the fp into the sp, to deallocate any
allocated space. - Restores saved registers including the ra, if
needed, using sp as base for displacement mode
addressing. - Adds the frame size to the sp, to deallocate the
frame. - Performs a jra instruction (jump back)
25Case Study 2
- Pascal (CodeWarrior v.9) on the Motorola 680x0.
(old Mac, Amiga, Atari ST) - CISC architecture.
- All arguments passed on the stack, not in
registers. - Arguments are pushed and popped (using auto
increment and auto decrement instruction modes),
updating the sp dynamically, rather than
assembling them in a pre-allocated area. - fp gets a dedicated register, by convention, a6.
26Pascal on M680x0
27Pascal on M680x0 (contd)
- The Caller
- allocates space for a small return value, or
pushes the address of a large one. Skip if this
is a procedure. - pushes arguments (or their addresses)
left-to-right. Skip if there are no parameters.
28Pascal on M680x0 (contd)
- The Callee, in the prologue
- executes a link instruction decrement sp enough
to accommodate all locals, temps, and large
arguments copied from caller. - pushes any registers that need to be saved (fp,
in a6). - copies any large arguments needed.
29Pascal on M680x0 (contd)
- The Callee, in the epilogue
- sets the return value (bottom of frame)
- pops saved registers.
- executes an unlk instruction, to restore the sp
- pops arguments and SL.
- returns.
30Pascal on M680x0 (contd)
- Since Pascal allows subroutines to be nested,
passing a subroutine as a parameter requires a
closure. - Eight-byte long closure
- First four are static link of closure
(environment link in RPAL). - Last four bytes are address of subroutine's code.
- Passed by address (due to its length), though
it's never changed.
31In-line expansion
- Compiler can choose to compile routine inline.
- Inline expansion increases code size, but is
significantly faster. - C
- inline int max (int a, int b)
- return a gt b ? a b
-
32In-line expansion (contd)
- Ada
- function max (a, b integer)
- return integer is begin
- if a gt b then return a else
- return b end if
- end max
- pragma inline (max)
- In both languages, the compiler directive is a
suggestion that can be ignored.
33Subroutines
Programming Language Principles Lecture 24
- Prepared by
- Manuel E. Bermúdez, Ph.D.
- Associate Professor
- University of Florida