C166 User's Guide

User Stack

The C16x architecture supports stack-relative addressing using the MOV [Ri+#displacement] and MOV [Ri-] instructions.

The Keil C166 Compiler uses the R0 register to maintain a user stack for parameter passing and for automatic (local) variables. The stack grows down from the top of memory. The size of the user-stack area and the user-stack pointer are defined and initialized in the startup code.

When passing arguments to a called function, the compiler stored them on the user stack in reverse order while decrementing the user stack pointer (R0) before each argument is "pushed" onto the stack. When a function with local variables is entered, it decrements the user stack pointer to make space for those local variables. For example:

Example Program
void func (char a, long b, int c)
{
char  x1, x2;
int   y;
float z;
.
.
.
}
 
Argument/VariableStack Position
int cR0 + 14
long bR0 + 10
GAPR0 + 9
char aR0 + 8
float zR0 + 4
int yR0 + 2
char x2R0 + 1
char x1R0 + 0

Note

  • The C166 Compiler optimizes some arguments and local variables into registers, which improves program performance and reduces the amount of stack space required. Optimizer level 0 disables this optimization and forces all arguments and local variables onto the stack. Refer to the OPTIMIZE directive for more information.
  • Single-byte variables (char and unsigned char) are passed as words on the user stack. The C166 Compiler inserts memory gaps to ensure the objects on the user stack are word-aligned. Word alignment of 16-bit, 32-bit, and 64-bit objects is required by the C16x architecture. Memory gaps are minimized as much as possible.