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