Compiling Procedure Calls -- Parameters


Consider the following example.

program main(input, output);
  var y, z : integer;
  procedure fred(a: integer; var b: integer);
    var x : integer;
    begin
      read(x);
      b := a + x;
      writeln('x = ', x, ' a = ',  a, ' b = ', b)
    end;
  begin {main}
    read(y, z);
    writeln('y = ', y, ' z = ', z);
    fred(y, z);
    writeln('y = ', y, ' z = ', z)
  end.

Notice that procedure fred has two parameters, one with the default mode (COPY) in and one with mode VAR.

A translation of this program is

br L1
L2:
; begin of procedure fred
; finish activation record for fred's local variables (just x in this case)
  add sp #1 sp
  ; read(x)
  rd 3(D1)
  ; a := a + 1
  push 0(D1)
  push #1
  adds
  pop 0(D1)
  ; b := a + x
  push 0(D1)
  push 3(D1)
  adds
  pop @1(D1)
  ; write(x, a, b)
  wrt 3(D1)
  wrt 0(D1)
  wrt @1(D1)
  ; pop fred's part of activation record
  sub sp #1 sp
  ; return to the calling routine -- remember that execution of the RET instruction
  ; pops the current top of stack into the PC, so the top stack value must be the
  ; return value that was pushed on at the pont of call
  RET
L1:
; begin main
; set up main's activation record
  push D0
  mov sp d0
  add sp #2 sp
  ; read(y, z)
  rd 0(D0)
  rd 1(D0)
  ; writeln(y, z)
  wrt 0(D0)
  wrt 1(D0)
  ; begin call to fred by setting up the first part of fred's activation record and
  ; pushing actual parameters
  push D1
  mov SP D1
  ;push y's value onto the stack as the first actual parameter (mode in)
  push 0(D0)
  ; compute and leave z's address on the stack as the second actual parameter (mode out)
  push d0
  push #1
  adds
  ; call fred -- remember that execution of this call instruction pushes the PC onto the
  ; stack, which means that the address of the wrt0(D0) instruction just below the call
  ; instruction is placed onto the stack
  call L2
  ; this is the point of return from fred, so we need to remove the rest of fred's
  ; activation record by moving the sp down two, past formal parameters a and b.
  sub sp #2 sp
  ; restore the old D1 value
  pop D1
  ; writeln(y, z)
  wrt 0(D0)
  wrt 1(D0)
  ; remove main's activation record
  sub sp #2 sp
  pop D0
  ; halt
  hlt