A function prologue typically does the following actions if the architecture has a base pointer (also known as frame pointer) and a stack pointer:
Several possible prologues can be written, resulting in slightly different stack configuration. These differences are acceptable, as long as the programmer or compiler uses the stack in the correct way inside the function.
As an example, here is a typical x86 assembly language function prologue as produced by the GCC
The N immediate value is the number of bytes reserved on the stack for local use.
The same result may be achieved by using the enter instruction:
More complex prologues can be obtained using different values (other than 0) for the second operand of the enter instruction. These prologues push several base/frame pointers to allow for nested functions, as required by languages such as Pascal. However, modern versions of these languages don′t use these instructions because they limit the nesting depth in some cases.
Function epilogue reverses the actions of the function prologue and returns control to the calling function. It typically does the following actions (this procedure may differ from one architecture to another):
The given epilogue will reverse the effects of either of the above prologues (either the full one, or the one which uses enter). Under certain calling conventions it is the callee's responsibility to clean the arguments off the stack, so the epilogue can also include the step of moving the stack pointer down or up.
For example, these three steps may be accomplished in 32-bit x86 assembly language by the following instructions:
Like the prologue, the x86 processor contains a built-in instruction which performs part of the epilogue. The following code is equivalent to the above code:
The leave instruction performs the mov and pop instructions, as outlined above.
A function may contain multiple epilogues. Every function exit point must either jump to a common epilogue at the end, or contain its own epilogue. Therefore, programmers or compilers often use the combination of leave and ret to exit the function at any point. (For example, a C compiler would substitute a return statement with a leave/ret sequence).