Compiled Stack Parameters

For non-reentrant functions using the compiled stack, the compiler will pass arguments in the W register, or in the called function’s parameter memory.

If the first parameter is one byte in size, it is passed in the W register. All other parameters are passed in the parameter memory. The parameter memory will be located in the compiled stack (see Compiled Stack Operation).

Parameters are referenced as an offset from the symbol ?_function, where function is the name of the function in which the parameter is defined (i.e., the function that is to be called).

Unlike auto variables, parameter variables are allocated memory strictly in the order in which they appear in the function’s prototype. This means that a function’s parameters will always be placed in the same memory bank; whereas auto variables for a function can be allocated across multiple banks and in any order.

The arguments for unnamed parameters in functions that take a variable argument list (defined using an ellipsis in the prototype), are placed in the parameter memory, along with named parameters.

Take, for example, the following prototyped function.

void test(char a, int b);

The function test() will receive the parameter b in parameter memory (using the two bytes ?_test and ?_test+1) and a in the W register.

The compiler needs to take special action if more than one function using the compiled stack can be indirectly called via the same function pointer. Such would be the case in the following example, where any of sp_ad, sp_sub or sp_null could be called via the pointer, fp.

int (*funcs[])(int, int) = {sp_add, sp_sub, sp_null};
int (*fp)(int, int);
fp = funcs[getOperation()];
result = fp(37, input);

In such a case, the compiler treats all three functions in the array as being “buddies.”

The parameter(s) to all buddy functions will be aligned in memory, i.e., they will all reside at the same address(es). This way the compiler does not need to know exactly which function is being called. The implication of this is that a function cannot call (either directly or indirectly) any of its buddies. To do so would corrupt the caller function’s parameters. An error will be issued if such a call is attempted.