old ebp
return address
parameter 1
parameter 2
parameter 3
With the advent of 64-bit architectures such as the AMD-64, this scheme has changed. There are 8 more general purpose registers in the 64-bit architecture (labeled r8 through r15) which can be used for parameter passing. These eight registers are labeled r8d through r15d if only 32 of their 64 bits need to be accessed.
The AMD64 Application Binary Interface (ABI for short) defines detailed rules about how these registers are to be used. We will look at only two important rules:
- Registers rbp, rbx, r12, r13, r14, r15 belong to the calling function. Mnemonic: the B registers (rBp, rBx) and r12-r15 belong to the caller.
- Integer arguments are passed in the following registers in order: rdi, rsi, rdx, rcx, r8, r9. Integer values are generally returned in the register rax.
Rule number 1. If function bar is called by function foo, then foo expects the values of the specified registers to be unchanged when bar returns. To adhere to this convention, the compiler generates code to preserve the values of these registers in the function prolog of bar. If you look at the disassembly of function bar, then you will see a few push instructions at the beginning; the number of push instructions depends on how many of the caller-owned registers are actually modified in the callee. Correspondingly the function epilog contains instructions to pop the saved values back into these registers before the function returns.
The other registers belong to the called function. Which means that the called function is not required to preserve the other registers and is free to modify their values.
Rule number 2. Notice that upto six integer arguments can be passed in registers. This covers the most common parameter types and eliminates parameter passing on the stack. This speeds up function calls quite a bit since there is no need to do memory reads and writes - just fill up the registers and call the function. Remember that memory access is two or more orders of magnitude slower than register access.
Neat, eh? Note that there are several other details involved that have been skipped in this description. You can refer to the AMD64 ABI for more information.