Module 0307: Parameters and local variables

Tak Auyeung, Ph.D.

October 23, 2017

1 About this module

2 Parameters on the stack

Because there can many parameters, and recursion is to be supported (along with multi-threading), it is necessary to store parameters in a per-invocation basis, much like the return address.

Let us examine the following caller code in C:

 
  subtract(3,5);

The equivalent code in TTP assembly is as follows:

 
1  ldi a,5 
2  dec d 
3  st  (d),a // push 5 
4  ldi a,3 
5  dec d 
6  st  (d),a // push 3 
7  ldi a,retAddr 
8  dec d 
9  st  (d),a // push return address 
10  jmpi subtract 
11retAddr: 
12  inc  d 
13  inc  d    // deallocate parameters 
14  // now the stack should be balanced

Note how the parameters are pushed in reverse order. This means the second parameter is pushed first, and then the first parameter. Another implication is that the first parameter has a lower address on the stack than the second parameter.

Furthermore, also note how the return address is pushed last.

Here is the subroutine code in C:

 
int subtract(int x, int y) 
{ 
  return x-y; 
}

The matching code in TTP assembly is as follows:

 
1subtract: // entry point of subroutine 
2  cpr c,d  // c is a copy of the stack pointer 
3  ldi a,1  // offset to find parameter x 
4  add c,a  // now c is the address to x 
5  ld  a,(c) // now a is parameter x 
6  inc c     // now c is the address to y 
7  ld  b,(c) // now b is parameter y 
8  sub a,b   // perform the subtraction 
9  // a already has the right result to return 
10  ld  b,(d) // d is never changed, still pointer 
11            // to the return address 
12  inc d     // callee only deallocates the retAddr 
13            // NOT the parameters! 
14  jmp b     // now return and continue in caller

It is important to leave register D alone and not to use it directly to compute the address of parameters.

3 Local variables

Local variables of a subroutine are allocated on a per invocation basis on the stack, much like parameters. However, parameters are allocated and initialized by the caller, while local variables are allocated by the called subroutine.

As a result, local variables have addresses that are below that of the return address. The method to access local variables is the same as accessing parameters.