Microchip Technology SW006022-1N Data Sheet

Page of 338
Functions
 2012 Microchip Technology Inc.
DS52071B-page 163
EXAMPLE 10-3: 
FUNCTION CALL MODEL, STACK BASED ARGUMENTS
typedef struct bar {
  double d,e;
} bar;
void
params2(int i, bar b, int j) {
        /*
        ** W0           i
        ** stack        b
        ** W1           j
        */
}
Accessing arguments that have been placed onto the stack depends upon whether or 
not a Frame Pointer has been created. Generally the compiler will produce a Frame 
Pointer (unless told not to do so), and stack-based parameters will be accessed via the 
Frame Pointer register (W14). In the preceding example, b will be accessed from 
W14-22. The Frame Pointer offset of negative 22 has been calculated (refer to 
Figure 7-4) by removing 2 bytes for the previous FP, 4 bytes for the return address, 
followed by 16 bytes for b.
When no Frame Pointer is used, the assembly programmer must know how much stack 
space has been used since entry to the procedure. If no further stack space is used, 
the calculation is similar to Example 10-3. b would be accessed via W15-20; 4 bytes 
for the return address and 16 bytes to access the start of b.
10.8.2
Return Value
Function return values are returned in W0 for 8- or 16-bit scalars, W1:W0 for 32-bit 
scalars, and W3:W2:W1:W0 for 64-bit scalars. Aggregates are returned indirectly 
through W0, which is set up by the function caller to contain the address of the 
aggregate value.
10.8.3
Preserving Registers Across Function Calls
The compiler arranges for registers W8-W15 to be preserved across ordinary function 
calls. Registers W0-W7 are available as scratch registers. For interrupt functions, the 
compiler arranges for all necessary registers to be preserved, namely W0-W15 and 
RCOUNT.