Verwirrung über Funktionsaufruf-Stack

8

Laut Wiki:

  

Der Aufrufer schiebt die Rücksprungadresse auf den Stapel und den Aufrufer   Unterprogramm, wenn es beendet ist, knallt die Rückkehradresse von dem Anruf   Stack und überträgt die Kontrolle an diese Adresse.

Bild vom Wiki:

Das verstehe ich nicht ganz. Angenommen, ich habe ein C-Programm wie folgt:

%Vor%

Und ich denke, der Call-Stack sollte so etwas wie eine Zeichnung sein:

%Vor%

Frage:

Nach den Worten aus Wiki,

  

Wenn die aufgerufene Subroutine beendet ist, wird die Rückkehradresse gelöscht   die Aufrufliste und überträgt die Kontrolle an diese Adresse.

1.Ist meine Zeichnung richtig?

2.Wenn es richtig ist, wird foo () beendet, es wird

  

Geben Sie die Rücksprungadresse vom Call-Stack aus und übertragen Sie die Kontrolle auf   diese Adresse

, aber wie kann es die Absenderadresse knacken?   Denn wenn foo fertig ist, zeigt der aktuelle Stapelzeiger auf den lokalen Spam,   richtig?

UPDATE:

Was ist, wenn main () so aussieht:

%Vor%

Wie sollte der Call-Stack aussehen?

    
Alcott 21.09.2011, 02:03
quelle

1 Antwort

14

Ihre Zeichnung ist nicht korrekt. Die lokalen Stapelvariablen für eine Funktion befinden sich alle unterhalb von Rückgabeadressen. Andernfalls, wie Sie gesehen haben, würden die Einheimischen verloren gehen, wenn Sie eine Funktion aufrufen.

Es sollte so sein:

%Vor%

Ich glaube, die Verwirrung besteht darin, dass Sie glauben, dass Variablendeklarationen als Anweisungen behandelt und der Reihe nach ausgeführt werden. Tatsächlich wird der Compiler in der Regel eine Funktion analysieren, um zu entscheiden, wie viel Stack-Platz für alle lokalen Variablen benötigt wird. Dann gibt es einen Code aus, um den Stapelzeiger entsprechend anzupassen, und diese Einstellung wird beim Eintritt in die Funktion vorgenommen. Alle Aufrufe anderer Funktionen können dann auf den Stapel geschoben werden, ohne den Stapelrahmen dieser Funktion zu beeinträchtigen.

    
David Heffernan 21.09.2011, 02:25
quelle

Tags und Links