5.8.5.1 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 5.7.2.1 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 in an array could be called via the pointer, fp.
int (*funcs[])(int, int) = {sp_add, sp_sub, sp_null};  /* an array of function addresses */
int (*fp)(int, int);                                   /* function pointer */

fp = funcs[getOperation()]; /* have the pointer reference the desired function */
result = fp(37, input);     /* call a function, but the compiler does not know which one*/
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 be forced to reside at the same address(es). This way the compiler does not need to know exactly which function is being called by the pointer. This also implies that if a function calls (either directly or indirectly) any of its buddies, the caller function’s parameters might be corrupted.

Important: Functions using the compiled stack and that are potentially called via the same function pointer should not call each other.

A warning will be issued if such a call is attempted. If the functions do need to call each other, have them use the software stack by using the appropriate function specifiers (see 5.8.1.3 Reentrant And Nonreentrant Specifiers) or swap to a reentrant stack model for the program (see 4.6.1.23 Stack Option).