Upload
lillian-welch
View
241
Download
0
Tags:
Embed Size (px)
Citation preview
Subprograms - implementation
Calling a subprogram
transferring control to a subprogram:1. save conditions in calling program2. pass parameters3. allocate local variables4. establish links to non-local variables5. begin execution of subprogram
Returning from a subprogram
returning control to a calling program:1. pass back parameters and function value2. deallocate local variables3. restore caller’s links to non-local variables4. restore conditions in calling program5. restart execution of calling program
General design
calling program
call sub
subprogram
return addressparameters
local variables...
activation record
flow of control
Using a compiled subprogram
compiled code + activation record
parameter space other local data space (function value) return address (in calling program) … more later
Simple Example - FORTRAN 77 (Sebesta)
linker puts executable program together: executable code for main program executable code for subprograms data space for main program data space for subprograms (activation
records)
Simple Example - FORTRAN 77
linked program with one subprogram Adata for main
activation record for sub A
code for main
code for sub A
execution starts here
call A
call A
at call save status of main put parameters in
activation record save ‘return address’ start sub A (*)
at call save status of main put parameters in
activation record save ‘return address’ start sub A (*)
at return put parameters (and
function value) in main restore status of main restart main at ‘return
address’
at return put parameters (and
function value) in main restore status of main restart main at ‘return
address’
*
FORTRAN 77 is simple
no nested subprograms no recursion parameter passing by value - result static memory allocation in subprograms non-local references outside of call-return
process (COMMON)
FORTRAN 77 <--> Algol, imperative language
FORTRAN 77no nested subprogramsno recursionparameters value-resultstatic memory allocationnon-local refs (COMMON)
Algolnested recursion and referencedynamicSCOPING
Standard imperative language
activation record created dynamically in statically scoped language
return address in caller
static link (scope)
dynamic link (caller AR)
parameters
local variables
activation record provided by caller
p.445
void sub(float total, int part){ int list[5]; float sum; …}
Standard imperative language page 446-447 example - no non-local
scope and no recursion page 448-450 example - recursion
void fun1(float r){ int s, t; … <------1 fun2(s); …}
void fun2(int x){ int y; … <------2 fun3(y); …}
void fun3(int q){ … <------3}
void main(){ float p; … fun1(p); …}
11 22 33
p.446-7
Standard imperative language page 446-447 example - no non-local
scope and no recursion page 448-450 example - recursion
p.448-50int factorial;(int n){
<------1 if (n<=1) return 1; else return
<------2}void main(){ int value; value = fact(3);
<------3}
ending recursive calls
Scoping – non-local references
all references are SOMEWHERE on the run-time stack
1. find the proper activation record instance2. find the reference (offset) in the ARI
two implementation strategies static chains displays (no longer popular)
Non-local references by static chaining
uses static link field in activation record
static link must refer to static parent of subprogram (not to caller)
nested static scopes are found by following the chain of static link fields
static depth – depth of nesting of a procedure: main program == 0
Non-local references by static chaining: static_depth, nesting_depthprogram main var x,y,w procedure sub1 var z,y procedure sub11 var z,w begin z = x + y * w end begin sub11() end begin sub1() end
static depth0
1
2
nesting depth, offset:
z: 0, 3
x: 2, 3
y: 1, 4
w: 0, 4
Setting the static link at call time
how to find the activation record of the static parent? search along dynamic links (slow,
especially with recursion) – depends on nesting of calls
use static links (faster – depends on static nesting only) but HOW?
Setting the static link at call time: how to find it?
program main var x,y,w procedure sub1 var y,z begin sub2() endprocedure sub2 var x,z begin sub1() end begin sub1() end
return addressstatic link dynamic linkparameterslocal variables
return addressstatic link dynamic linkparameterslocal variables
return addressstatic link dynamic linkparameterslocal variables
return addressstatic link dynamic linkparameterslocal variables
return addressstatic link dynamic linkparameterslocal variables
return addressstatic link dynamic linkparameterslocal variables
main
sub1
sub2
sub1
sub2
sub1
Scope bystatic chaining
page 455-457 – Ada
Main_2Bigsub
Sub1
Sub2Sub3
procedure Main_2 is X: Integer; procedure BigSub is A,B,C: Integer; procedure Sub1 is A,D: Integer; begin -- of Sub1 A := B + C; <----1 end; -- Sub1 procedure Sub2(X: Integer) is B,E: Integer; procedure Sub3 is C,E: Integer; begin -- Sub3 Sub1; E := B + A; <----2 end; -- Sub3 begin -- Sub2 Sub3; A := D + E; <----3 end; -- Sub2 begin -- Bigsub Sub2(7); end; -- Bigsub begin -- Main_2 BigSub;end; -- Main_2
Setting static link using caller static links
At call: SUB3 calls SUB1 static depth of caller SUB3 - 3 static depth of parent of SUB1 (BIGSUB) - 1 nesting depth (difference) 3-1 = 2 follow caller’s (SUB3) static chain 2 links to
parent (BIGSUB) of called subprogram (SUB1) put address of parent (BIGSUB) in static link
field of subprogram (SUB1)
procedure Main_2 is X: Integer; procedure BigSub is A,B,C: Integer; procedure Sub1 is A,D: Integer; begin -- of Sub1 A := B + C; <----1 end; -- Sub1 procedure Sub2(X: Integer) is B,E: Integer; procedure Sub3 is C,E: Integer; begin -- Sub3 Sub1; E := B + A; <----2 end; -- Sub3 begin -- Sub2 Sub3; A := D + E; <----3 end; -- Sub2 begin -- Bigsub Sub2(7); end; -- Bigsub begin -- Main_2 BigSub;end; -- Main_2
Blocks
block scopes are like procedures but their order of activation is fixed at compile time
consecutive blocks can share space in AR of procedure
re-used identifier names distinguished by offset
Dynamic scoping
‘deep access’ - follow dynamic chain can be slo-o-o-o-o-ow
‘shallow access’
Dynamic scoping
‘deep access’ ‘shallow access’ – local variables
are not in activation records; each has its own stack
Shallow access by variable stacksproc A var x=2, y=3, z=4 begin call B endproc B var x=22, w=55, t=66 begin call C endproc C var x=222, y=333, w=555 begin call B end main var r=0,t=0 begin call A end
r
t
w
x
y
z
while in C:
222 22 2
66 0
555 55
333 3
4
0