путаница по поводу стека вызовов функций

Согласно Wiki:

вызывающая сторона помещает адрес возврата в стек, и Вызываемая подпрограмма по завершении извлекает адрес возврата из стека вызовов и передает управление этому адресу.

Рисунок из Wiki:

enter image description here

Я этого не совсем понимаю. Допустим, у меня есть следующая программа на 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();
}

, тогда как должен выглядеть стек вызовов?

10
задан Alcott 21 September 2011 в 04:13
поделиться