Unit content
Machine-level function calls and calling conventions
At source level, a function call looks like a transfer of values into a named operation. At machine level, the caller and callee must agree exactly on where arguments, results and preserved state are placed.
That agreement is a calling convention, usually defined as part of a platform's application binary interface (ABI).
Transferring control
A call must record a return address and transfer execution to the callee. Different instruction sets encode this differently, but the logical requirement is the same: when the callee finishes, execution must resume at the instruction after the call.
Arguments and return values
Calling conventions specify where parameters are passed. Common designs use a sequence of registers for the first arguments and the stack for additional ones.
The return value is also placed in a defined register or set of registers so the caller knows where to find it.
Caller-saved and callee-saved registers
Both caller and callee use processor registers. The convention divides responsibility for preserving them.
- A caller-saved register may be overwritten by the called function, so the caller saves it first if its current value is still needed.
- A callee-saved register must be restored by the called function before it returns if the callee changes it.
This contract allows independently compiled functions to interoperate.
Stack frames
A function can reserve stack space for local data, spilled register values and saved state. A typical entry sequence may adjust the stack pointer and save registers; the exit sequence reverses those actions.
These patterns are often called a function prologue and epilogue, although optimizing compilers can omit or rearrange them when the ABI permits.
Stack alignment
ABIs normally require the stack pointer to satisfy an alignment rule at call boundaries. Correct alignment can be necessary for instruction requirements and efficient access to data.
Function pointers and indirect calls
When the target is not known statically, a program can call through an address stored in a register or memory. The calling convention still applies; only the way the target address is selected changes.
A processor does not inherently understand a source-language notion such as “three parameters and one local variable.” Compilers implement that abstraction by generating machine instructions that obey a shared calling convention.