a) |
Caller Function Stack Frame |
b) |
Caller Function Stack Frame |
c) |
Caller Function Stack Frame |
d) |
Caller Function Stack Frame |
argument1 |
argument2 |
argument2 |
argument1 |
||||
argument2 |
argument1 |
argument1 |
Return Value %eax |
||||
Return Address |
Return Address |
Return Value %eax |
Return Address |
||||
Saved %ebp |
Saved %ebp |
Saved %ebp |
Saved %ebp |
||||
Called Function Stack Frame |
Called Function Stack Frame |
Called Function Stack Frame |
Called Function Stack Frame |
Call stack layout for upward-growing stacks
A diagram like this can be drawn in either direction as long as the placement of the top, and so direction of stack growth, is understood. Furthermore, independently of this, architectures differ as to whether call stacks grow towards higher addresses or towards lower addresses. The logic of the diagram is independent of the addressing choice.
The stack frame at the top of the stack is for the currently executing routine. The stack frame usually includes at least the following items (in push order):
Storing the address to the caller's frame
In most systems a stack frame has a field to contain the previous value of the frame pointer register, the value it had while the caller was executing. For example, the stack frame of DrawLine would have a memory location holding the frame pointer value that DrawSquare uses (not shown in the diagram above). The value is saved upon entry to the subroutine and restored upon return. Having such a field in a known location in the stack frame enables code to access each frame successively underneath the currently executing routine's frame, and also allows the routine to easily restore the frame pointer to the caller's frame, just before it returns.
Therefore the correct answer for question 2 is option b.
A program's instructions are loaded into memory from the base pointer and loaded up in memory. Therefore the correct answer for question 1 is option b.
Get Answers For Free
Most questions answered within 1 hours.