Hardware manual

4.8. The Bcpl stack
The Bcpl compiler determines the format of a frame and the calling convention. The strategy for allocating
stack frames, however, is determined by the operating system. We begin by describing the compiler
conventions, which are useful to know for writing machine-language routines.
A procedure call: p(a1, a2, ...), is implemented in the following way. The first two actual arguments are
put into AC0 and AC1 (AC2 always contains the address of the current frame, except during a call or
return). If there are exactly three actual arguments, the third is put into F.extraArguments. If there are
more than three, the frame-relative address of a vector of their values is put there (except for the first two),
so that the value of the i-th argument (counting from 1) is frame>>F.extraArguments!(frame+i). Once the
arguments are set up, code to transfer control is generated which puts the old PC into AC3 and sets the PC
to p. At this point, AC3!0 will be the number of actual arguments, and the PC should be set to AC3+1 to
return control to the point following the call.
A procedure declaration: let p(f1, f2, ...) be ..., declares p as a static whose value after loading will be the
address of the instruction to which control goes when p is called. The first four instructions of a procedure
have a standard form:
STA 3 1,2 ; AC2>>F.savedPC _ AC3
JSR @GETFRAME
<number of words needed for this procedure’s frame>
JSR @STOREARGS
The Bcpl runtime routine GETFRAME allocates storage for the new frame, NF, saves AC2 in
NF>>F.callersFrame field, sets AC2 to NF, and stores the values of AC0 and AC1 (the first two
arguments) at NF>>F.formals ^0 and 1. If there are exactly three actual arguments, it stores the third one
also, at NF>>F.formals ^2. Then, if there are three or fewer actual arguments, it returns to L+3, otherwise
it returns to L+2 with the address of the vector of extra arguments in AC1; at this point a JSR
@STOREARGS will copy the rest of the arguments. In both cases, the number of actual arguments is in
AC0, and this is still true after a call of STOREARGS. A Bcpl procedure returns, with the result, if any, in
AC0, by doing:
JMP @RETURN
to a runtime routine which simply does:
LDA 2 0,2 ; AC2_AC2>>F.callersFrame
LDA 3 1,2 ; PC_AC2>>F.savedPC+1
JMP 1,3
The information above is a (hopefully) complete description of the interface between a Bcpl routine and
the outside world (except for some additional runtime stuff which is supplied by the operating system).
Note that it is OK to use the caller’s F.Temp and F.extraArguments in a machine-language routine which
doesn’t get its own frame, and of course it is OK to save the PC in the caller’s F.savedPC.
The operating system currently allocates stack space contiguously and grows the stack down. To allocate a
new frame of size S, it simply computes NF=AC2-S-2 and checks to see whether NF > EndCode. If not,
there is a fatal error (Swat breakpoint at finish+1); if so, NF becomes the new frame. (Note: the "-2" in
the computation is an unfortunate historical artifact.)
4.9. Run files
The format of a file produced by Bldr to be executed by CallSubsys is described by the structure definition
SV in BCPLFiles.d. Consult the Bcpl manual (section on Loading) for interpretations of the various fields
and the handling of overlays.
Alto Operating System May 5, 1980 26
For Xerox Internal Use Only -- December 15, 1980