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