C Stack



  • @DirkB sagte in C Stack:

    @Bushmaster sagte in C Stack:

    bevor die funktion verlassen wird, wird der stack wieder bereinigt.

    Das mag für Pascal gelten, aber nicht für C.

    In C räumt der Caller den Stack auf, da die Funktion nicht weiß, mit wieviel Parametern sie aufgerufen wurde.

    danke für die berichtigung. die funktion wird aber wohl ihre lokalen variablen von stack nehmen. denn damit hat der caller ja nichts zu tun.



  • @Bushmaster sagte in C Stack:

    die funktion wird aber wohl ihre lokalen variablen von stack nehmen.

    Wie soll sie das denn machen?
    Gelöscht (überschrieben) wird nicht.

    Die Funktion ruft die Rücksprungadresse auf und der Caller setzt den Stack so, wie vor dem Aufruf. Somit sind auch die lokalen Variablen der Funktion ungültig. Die Daten sind aber noch da.



  • @DirkB sagte in C Stack:

    Wie soll sie das denn machen?

    sie setzt den stackpointer wieder auf den wert, wie er beim eintritt in die funktion war. damit sind die lokalen variablen nicht mehr existent.



  • #include <stdio.h>
    
    int F1(double x, double y)  
    {
        int i[3];
        double n;
    
     /*hier adresse von SBP und SP angeben*/
        unsigned ebp,esp;
        asm volatile ("movl %%ebp,%0" : "=r" (ebp));
        asm volatile ("movl %%esp,%0" : "=r" (esp));
        printf("%lX\n%lX",ebp,esp);
    
        n = 6.04 * x - 8.5;
        return (n);
    }
    
    int main()  
    {
        double a, b, c;
        a = 10;
        b = 10;
        F1(a, b);
        return 0;
    }
    

    FF9C28D8
    FF9C28A0

    http://codepad.org/z1BZV02T



  • @Bushmaster sagte in C Stack:

    sie setzt den stackpointer wieder auf den wert, wie er beim eintritt in die funktion war. damit sind die lokalen variablen nicht mehr existent.

    Das ist überflüssig, da das der Caller gleich nochmal macht - für die Funktionsparameter, zudem sind die Daten immer noch da.



  • @DirkB sagte in C Stack:

    Das ist überflüssig, da das der Caller gleich nochmal macht - für die Funktionsparameter, zudem sind die Daten immer noch da.

    ich hab den aufruf mal disassemblen lassen

        F1(a, b);
    00152072  sub         esp,8  
    00152075  movsd       xmm0,mmword ptr [b]  
    0015207A  movsd       mmword ptr [esp],xmm0  
    0015207F  sub         esp,8  
    00152082  movsd       xmm0,mmword ptr [a]  
    00152087  movsd       mmword ptr [esp],xmm0  
    0015208C  call        F1 (015103Ch)  
    00152091  add         esp,10h  
    
    

    die main-funktion tut die beiden doubles auf den stack und, dann die return-adresse (durch den call) und räumt den stack danach mit add esp, 16 wieder auf. falls die andere funktion den esp verändert hat, würde das schief gehen. also geht main davon aus, dass die andere funktion ihren dreck auch wieder weg macht. 🙂



  • @Bushmaster sagte in C Stack:

    also geht main davon aus, dass die andere funktion ihren dreck auch wieder weg macht.

    Danke für die Klarstellung.





  • Hallo zusammen,

    erstmal danke für die Antworten! Hat mich sehr gefreut.

    Zusammengefasst müsste also der Stack nach dem Funktionsaufruf leer sein?
    Danke an @Wutz habe einfach ein paar mehr Ausgaben hinzugefügt:
    http://codepad.org/wmJ3CxxI
    BP und SP zeigen auf die gleichen Adressen wie am Anfang von main.

    BP:
    Zeigt in der geforderten Zeile auf die Return Adresse

    SP:
    Adresse ergibt sich aus den Werten der beiden Double Variablen und dem Call ?

    Sehe ich das so richtig?



  • @sh_run sagte in C Stack:

    Zusammengefasst müsste also der Stack nach dem Funktionsaufruf leer sein?

    Zusammengefasst ist der Stack Pointer nachher wo er vorher war. Wo genau "vorher" und "nachher" ist halt abhängig von der Calling Convention.


Anmelden zum Antworten