[英]confusion about function call stack
根据维基:
调用者将返回地址压入堆栈,被调用的子例程一旦完成,就会从调用堆栈中弹出返回地址并将控制权转移到该地址。
来自Wiki的图片:
我不太明白这一点。 说我有一个C程序如下:
#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;
}
我认为调用堆栈应该类似于绘图,如下所示:
<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> |
题:
根据Wiki引用的字样,
被调用的子程序,当它完成时,从调用堆栈中弹出返回地址并将控制转移到该地址。
我的抽签是对的吗?
2.如果它是正确的,那么当foo()完成时,它会
弹出调用堆栈的返回地址并将控制权转移到该地址
,但它如何弹出退货地址? 因为当foo完成时,当前的堆栈指针指向垃圾邮件的本地,对吧?
更新:
如果main()看起来像这样:
int main()
{
spam();
foo();
}
然后调用堆栈应该是什么样的?
你的图纸不正确。 函数的本地堆栈变量都低于任何返回地址。 否则,正如您所观察到的,当您调用函数时,本地人会迷失方向。
它应该是这样的:
| 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> |
我认为令人困惑的是,您认为变量声明被视为语句并按顺序执行。 实际上,编译器通常会分析一个函数来决定所有局部变量需要多少堆栈空间。 然后它发出代码来相应地调整堆栈指针,并在进入函数时进行调整。 然后,对其他函数的任何调用都可以推入堆栈,而不会干扰此函数的堆栈帧。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.