According to Wiki:
the caller pushes the return address onto the stack, and the called subroutine, when it finishes, pops the return address off the call stack and transfers control to that address.
Pic from Wiki:
I don't quite understand this. Say I have a C program as follows:
#include <stdio.h>
int foo(int x)
{
return x+1;
}
void spam()
{
int a = 1; //local variable
int b = foo(a); //subroutine called
int c = b; //local variable
}
int main()
{
spam();
return 0;
}
And I think the call stack should be something like a drawing as follows:
<None> means none local variables or params
_| parameters for foo() <int x> |_
top | local of spam() <int c> |
^ | return address of foo() |<---foo() called, when finishes, return here?
| | local of spam() <int b> |
bot | local of spam() <int a> |
_| parameters for spam() <None> |_
| locals of main() <None> |
| return address of spam() |<---spam() called, when finishes, return here?
| parameters for main() <None> |
Question:
According to the words quoted from Wiki,
the called subroutine, when it finishes, pops the return address off the call stack and transfers control to that address.
1.Is my drawing right?
2.If it is right, then when foo() finishes, it will
pop the return address off the call stack and transfer control to that address
, but how can it pop off the return address? Because when foo finishes, the current stack pointer is pointing to spam's local , right?
UPDATE:
what if the main() looks like this:
int main()
{
spam();
foo();
}
then what the call stack should look like?
Now, whenever a function is called a new stack frame is created with all the function's data and this stack frame is pushed in the program stack, and the stack pointer that always points the top of the program stack points the stack frame pushed as it is on the top of the program stack.
When a function call is made, function's arguments are PUSHed on stack. These arguments are further referenced by base pointer. When the function returns to its caller, the arguments of the returning function are POPed from the stack using LIFO method.
The function call stack (often referred to just as the call stack or the stack) is responsible for maintaining the local variables and parameters during function execution.
In computer science, a call stack is a stack data structure that stores information about the active subroutines of a computer program. This kind of stack is also known as an execution stack, program stack, control stack, run-time stack, or machine stack, and is often shortened to just "the stack".
Your drawing is not correct. The local stack variables for a function are all below any return addresses. Otherwise, as you have observed, the locals would get lost when you call a function.
It should be like this:
| parameters for foo() <int x> |
| return address of foo() |
| local of spam() <int c> |
| local of spam() <int b> |
| local of spam() <int a> |
| parameters for spam() <None> |
| return address of spam() |
| locals of main() <None> |
| parameters for main() <None> |
I think the confusion is that you believe that variable declarations are treated as statements and executed in order. In fact the compiler will typically analyse a function to decide how much stack space is needed for all the local variables. Then it emits code to adjust the stack pointer accordingly and that adjustment is made on entry to the function. Any calls to other functions can then push onto the stack without interfering with this function's stack frame.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With