Module 0373: Callee only considerations

Tak Auyeung

1 Callee only considerations

2 A more structured way to look at stack use

address item comment
high \(\mathrm{arg}_{n-1}\) optional, caller pushes
\(\mathrm{arg}_{0}\) optional, optional, caller pushes
return address mandatory, caller pushes, the SP points here at entry point of the callee
last local variable optional, allocated by callee
low first local variable optional, allocated by callee, the SP points here after local var allocation

This can be reflected using label definitions. Each label defines an offset from where the SP points to after local variables (if any) is allocated:

firstLocalVar: 0
secondLocalVar: firstLocalVar firstLocalVarSize +
// ...
lastLocalVar: secondLastLocalVar secondLastLocalVarSize +
localVarSize: lastLocalVar lastLocalVarSize +
retAddr: localVarSize
arg0: retAddr 1 +
arg1: arg0 arg0Size +
// ...
argLast: argSecondLast argSecondLastSize +

The label localVarSize is useful for the allocation and deallocation of local variables. To allocate, decrease the SP by this amount. To deallocate, increase the SP by this amount.

Keep in mind, however, that TTPASM is a single file. This means these labels should be prefixed by the subroutine to make sure there is no name collision.

Using such label definition, the allocation of local variables at the entry point of a function is uniform:

ldi a,localVarSize
sub d,a

This is matched by the code to deallocate the local variables at the end of the subroutine, just prior to popping the return address.

ldi a,localVarSize
add d,a

In between the allocation and deallocation of the stack space for local variables, local variables can be accessed the same way as parameters.

3 Recognizing patterns

It can be helpful to recognize patterns of instructions. For example, the following is a push operation:

  dec d
  ldi a,value
  st  (d),a

However, it is also important not to be over-specific because the dec d instruction can exchange order with the ldi instruction in this case. As a result, it is more helpful to recognize a more general pattern:

// some instructions that do not work with reg D
dec d
// some instructions that do not work with reg D
st  (d),a // reg A is just an example, can be any register

Note that in this case, as long as register A is determined prior to the st (d),a instruction, and the value of register A does not depend on the value of register D, register A can be set before or after the dec d instruction.