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