F28xx: How a Function Makes a Call
How a Function Makes a Call. Taken from document spru514c.pdf by Texas Instruments.
1 Function Structure and Calling Conventions
The C/C++ compiler imposes a strict set of rules on function calls. Except for special run-time support functions, any function that calls or is called by a C/C++ function must follow these rules. Failure to adhere to these rules can disrupt the C/C++ environment and cause a program to fail.
Figure 1 illustrates a typical function call. In this example, parameters that cannot be placed in registers are passed to the function on the stack. The function then allocates local variables and calls another function. This example shows the allocated local frame and argument block for the called function. Functions that have no local variables and do not require an argument block do not allocate a local frame.
The term argument block refers to the part of the local frame used to pass arguments to other functions. Parameters are passed to a function by moving them into the argument block rather then pushing them on the stack. The local frame and argument block are allocated at the same time.
Figure 1. Use of the Stack During a Function Call
2 How a Function Makes a Call
A function performs the following tasks when it calls another function:
- Any registers whose values are not necessarily preserved by the function being called (registers that are not save-on-entry (SOE) registers), but will be needed after the function returns are saved on the stack.
- If the called function returns a structure, the calling function allocates the space for the structure and pass the address of that space to the called function as the first argument.
- Arguments passed to the called function are placed in registers and, when necessary, placed on the stack.
- Arguments are placed in registers using the following scheme:
- If the target is FPU and there are any 32-bit float arguments, the first four float arguments are placed in registers R0H-R3H.
- If there are any 64-bit integer arguments (long long), the first is placed in ACC and P (ACC holds the upper 32 bits and P holds the lower 32 bits). All other 64-bit arguments are placed on the stack in reverse order. If the P register is used for argument passing, then prolog/epilog abstraction is disabled for that function. See Section 3.8 for more information on abstraction.
- If there are any 32-bit arguments (longs or floats) the first is placed in the 32-bit ACC (AH/AL). All other 32-bit arguments are placed on the stack in reverse order.
func1(long a, long long b, int c, int* d);
stack, ACC/P , XAR5, XAR4
- Pointer arguments are placed in XAR4 and XAR5. All other pointers are placed on the stack.
- Remaining 16-bit arguments are placed in the order AL, AH, XAR4, XAR5 if they are available.
- Any remaining arguments not placed in registers are pushed on the stack in reverse order. That is, the leftmost argument that is placed on the stack is pushed on the stack last. All 32-bit arguments are aligned to even addresses on the stack. A structure argument is passed as the address of the structure. The called function must make a local copy. For a function declared with an ellipsis, indicating that it is called with varying numbers of arguments, the convention is slightly modified. The last explicitly declared argument is passed on the stack so that its stack address can act as a reference for accessing the undeclared arguments.
- The stack pointer (SP) must be even-aligned by the parent function prior to making a call to the child function. This is done by incrementig the stack pointer by 1, if necessary. If needed, the coder shoud increment the SP before making the call. Some examples of function calls that show where arguments are placed are listed below:
func1 (int a, int b, long c);
XAR4, XAR5, AH/AL
func1 (long a, int b, long c);
AH/AL, XAR4, stack
vararg (int a, int b, int c, ...);
AL, AH , stack
- The caller calls the function using the LCR instruction. The RPC register value is pushed on the stack. The return address is then stored in the RPC register.
- The stack is aligned at function boundary.
3 Additional Tags