mikrocontroller.net

Forum: Compiler & IDEs Variablen auf Stack, Leerräume


Autor: Thomas W. (thomas_v2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hallo,
ich habe mir gerade mal angesehen, wie bei einem C-Programm die 
Variablen auf dem Stack abgelegt werden.

Testfunktion
void test()
{
    int var1;                   // -0c
    unsigned char var2[8];      // [0] = -1c, [1] = -1b, [7] = -15
    struct tt {
        unsigned int aa;        // -34
        unsigned int bb;        // -30
        unsigned int cc;        // -2c
        unsigned int dd;        // -28
    } stt;
    int var3;                   // -40
}

Im Kommentar ist der Adressoffset zu ebp angegeben.

Dabei ist mir aufgefallen, dass zwischen einzelnen Variablen auf dem 
Stack immer 8 Bytes freigelassen werden. Hat das einen bestimmten Grund?

Getestet habe ich mit VS2013 unter 32-Bit Windows (x86).

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas W. schrieb:
> Hat das einen bestimmten Grund?

Je nach Compilereinstellung können das "stack guards" sein, mit denen 
die Runtime-Library Stackfehler und Variablenläufe erkennen kann.

Autor: Thomas W. (thomas_v2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:

> Je nach Compilereinstellung können das "stack guards" sein, mit denen
> die Runtime-Library Stackfehler und Variablenläufe erkennen kann.

Dieser "Security Cookie" liegt an offset -4, dazwischen auch wieder 4 
Bytes frei und dann kommt die erste Variable.

Ja, zur Zeit übersetze in mit den Debug-Einstellungen. Dieser freie 
Platz führt doch sogar eher dazu, dass ich eventuelle Fehler nicht 
entdecke, weil nicht eine andere Variable, sondern unbenutzer Bereich 
überschrieben wird.

Autor: Dumdi D. (dumdidum)
Datum:

Bewertung
-1 lesenswert
nicht lesenswert
Alignment?

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
2 lesenswert
nicht lesenswert
Thomas W. schrieb:
> Dieser freie Platz führt doch sogar eher dazu, dass ich eventuelle
> Fehler nicht entdecke, weil nicht eine andere Variable, sondern
> unbenutzer Bereich überschrieben wird.

Beim Verlassen eines Blocks wird vom Runtime-Code der freie Platz 
überprüft, ob er sich geändert hat.

D.h. beim Betreten eines Blocks wird der benutzte Bereich des Stacks mit 
einem definierten Bitmuster (0xCD, wenn ich mich recht erinnere) 
initialisiert, und beim Verlassen des Blocks das Vorhandensein dieses 
Bitmusters in den Lücken geprüft.

Autor: Thomas W. (thomas_v2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Rufus Τ. F. schrieb:

> D.h. beim Betreten eines Blocks wird der benutzte Bereich des Stacks mit
> einem definierten Bitmuster (0xCD, wenn ich mich recht erinnere)
> initialisiert, und beim Verlassen des Blocks das Vorhandensein dieses
> Bitmusters in den Lücken geprüft.

Ah, ok.

Der Anfang der Funktion sieht bei mir so aus:
push    ebp
mov     ebp, esp
sub     esp, 104h
push    ebx
push    esi
push    edi
lea     edi, [ebp+var_104]
mov     ecx, 41h
mov     eax, 0CCCCCCCCh
rep stosd
mov     eax, __security_cookie
xor     eax, ebp
mov     [ebp+var_4], eax
mov     [ebp+var_C], 0AAAAh
Die letzte Anweisung ist die erste aus meinem C-Code (var1 = 0xaaaa;)

D.h. da werden zu Beginn 260 Bytes auf dem Stack mit 0xcc beschrieben

Wobei dann die Stack-Check Funktion wissen müsste, an welcher Stelle die 
Variablen auf dem Stack abgelegt werden, um auch die Lücken zu 
überprüfen. Dazu sieht mir diese Funktion aber zu kurz aus.

Autor: Rufus Τ. F. (rufus) (Moderator) Benutzerseite
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Thomas W. schrieb:
> Dazu sieht mir diese Funktion aber zu kurz aus.

Die ist es ja auch nicht. Die Überprüfung übernimmt eine Funktion, die 
erst nach dem Verlassen des Blocks aufgerufen wird.

Autor: Thomas W. (thomas_v2)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es ist die Compileroption /RTC die das verursacht. Ohne diese sind auch 
keine Lücken mehr vorhanden.

https://msdn.microsoft.com/de-de/library/8wtf2dfz.aspx

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.