2011-09-21 17 views
8

Según Wiki:confusión acerca de la función de llamada pila

la persona que llama empuja la dirección de retorno en la pila, y la llamada subrutina, cuando termina, aparece la dirección de retorno de la de control de llamadas pila y transferencias a esa dirección.

Pico de wiki:

enter image description here

yo no entiendo muy bien esto. Decir que tengo un programa en C de la siguiente manera:

#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; 
} 

Y creo que la pila de llamadas debe ser algo así como un dibujo de la siguiente manera:

<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> | 

Pregunta:

De acuerdo con las palabras citadas de Wiki,

la subrutina llamada, cuando termina, aparece la dirección de retorno la pila de llamadas y transfiere el control a esa dirección.

1.Is mi dibujo correcto?

2. Si es correcto, entonces cuando foo() termina, será

estallar la dirección de retorno de la pila de llamadas y control de transferencia de que abordan

, pero ¿cómo ¿puede aparecer la dirección de retorno? Porque cuando termina foo, el puntero de pila actual apunta al local de spam, ¿verdad?

ACTUALIZACIÓN:

¿y si el main() es el siguiente:

int main() 
{ 
    spam(); 
    foo(); 
} 

entonces lo que la pila de llamadas debe ser similar?

Respuesta

14

Su dibujo no es correcto. Las variables de pila locales para una función están todas debajo de cualquier dirección de retorno. De lo contrario, como habrás observado, los lugareños se perderían cuando llamas a una función.

Debería ser así:

| 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> | 

Creo que la confusión es que usted cree que las declaraciones de variables son tratados como declaraciones y se ejecutan en orden. De hecho, el compilador normalmente analizará una función para decidir cuánto espacio de pila se necesita para todas las variables locales. Luego emite un código para ajustar el puntero de la pila en consecuencia y ese ajuste se realiza al ingresar a la función. Cualquier llamada a otras funciones puede presionar sobre la pila sin interferir con el marco de pila de esta función.

+0

sí, señor, estoy de acuerdo con usted. Pero en "spam()", se llama a "foo()" antes de "", ¿verdad? Entonces, ¿dónde debería poner "int c" en la pila de llamadas? ¿También debajo de la dirección de devolución? – Alcott

+3

La reserva de pila de las variables locales generalmente se realiza de una vez por todas al inicio de la ejecución de la función. Entonces, a, byc son todos espacios de pila reservados antes de llamar a foo. –

+0

Entendido, señor. ¿Qué pasa si llamo spam() y foo() en main (ver UPDATE)? ¿Cómo se verá la pila de llamadas? ¿Quiere decir que el tamaño del marco de pila de una función es la suma del tamaño de su población local? – Alcott

Cuestiones relacionadas