Subroutine calling sequence:When subroutine is called, there is a call stack that is maintained in the memory. When a subroutine is called, its program counter is needed to be set from its caller (calling function) to callee (called function). It also needs the data to work on, with space to return the value generated (returned by called function). For this the instructions that are used is known as calling sequence.
Stack Frame diagram:
Calling sequence has three components:
• The code performed by the subroutine’s caller before and after the call.
• Prologue: code executed at the beginning of the subroutine.
• Epilogue: code executed at the end of the subroutine.
A typical stack frame is as shown below:
Before the subroutine code can be executed, the below things need to be done in the calling sequence are:
• Passing parameters
• Saving the return address and registers
• Setting the program counter and stack pointer
• Performing any initialization
Before the subroutine code is executed, the below things need to be done in the calling sequence:
• Passing return values and parameters
• Deallocating the stack pointer and frame pointer (restoring fp and sp to their previous value)
• Restoring saved registers and program counter (as previously saved)
For an example, calling a subroutine foo(a,b):
Steps performed before the call, are:
1. Move stack pointer to allocate a new stack frame.
2. Copy arguments a, b into frame.
3. Copy the return address into frame.
4. Set frame pointer to point to new frame.
5. Set the program counter.
6. Copy the registers into local slots.
7. Performing the object initialization.
Steps performed after the call, are:
1. Passing the return values
2. Restore registers.
3. Restore program counter.
4. Deallocate the stack pointer and frame pointer.