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.
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.
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).