Согласно Wiki:
вызывающая сторона помещает адрес возврата в стек, и Вызываемая подпрограмма по завершении извлекает адрес возврата из стека вызовов и передает управление этому адресу.
Рисунок из 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,
вызываемая подпрограмма по завершении извлекает адрес возврата из стека вызовов и передает управление этому адресу.
1. Правильно ли мой рисунок?
2. Если он правильный, то, когда foo () завершит свою работу, он
извлечет адрес возврата из стека вызовов и передаст управление , который адрес
, но как он может вытолкнуть адрес возврата? Поскольку, когда foo завершается, текущий указатель стека указывает на локальный адрес спама, верно?
ОБНОВЛЕНИЕ:
что, если main () выглядит так:
int main()
{
spam();
foo();
}
, тогда как должен выглядеть стек вызовов?