confusion about function call stack

限于喜欢 提交于 2019-12-03 17:25:03

问题


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?


回答1:


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.



来源:https://stackoverflow.com/questions/7493785/confusion-about-function-call-stack

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!