Stack / Heap: Grundlegende Frage



  • Was in C# auf den Stack und Heap kommt ist eigentlich klar. Nur was mir nicht ganz klar ist: Ich kenne den Stack in Assembler, wo ich mit push jeweils eine Variable in den Stack bringe und mit pop wieder hole, und wenn ich eine Variable will welche "weiter hinten" im Stack liegt muss ich so oft pop ausführen bis ich an diese Variable gelange, also keinen direkten Zugriff.

    Andererseits können in Assembler mit dd/dw/db usw. Bytes, Words oder Doublewords etc. deklariert werden für normalen Zugriff wie bei C# auf Ints, Doubles etc.

    In C# ist es doch so dass Grunddatentypen (keine Objekte in dem Sinn) auf dem "Stack" generiert werden und Objekte auf dem Heap. Hat dieser Stack nun etwas mit dem Stack von ASM zu tun?
    Kann ja fast nicht sein, auf einen int hat man ja genau den direkten Zugriff, wie in Assembler auf ein Doubleword (was es ja auch ist). Warum Stack?
    Bei Objekten ist ja eigentlich die Anfangsadresse in einer Variablen gespeichert, so inn Etwa wie Windows-/oder C-Funktionen um Speicher dynamisch zu reservieren, stimmt das?

    Vielen Dank 🙂



  • C. M. Obrecht schrieb:

    In C# ist es doch so dass Grunddatentypen (keine Objekte in dem Sinn) auf dem "Stack" generiert werden und Objekte auf dem Heap.

    Das ist nur fast richtig.

    Value Type werden auf dem Stack angelegt, Reference Types auf dem Heap. In C# erkennt man value types an dem "struct" und reference Types an dem "class".

    Und ja, JEDES Programm hat einen Programmstack. Das ist unabhängig von der benutzten Sprache. Unterschiedlich ist nur wie die jeweilige Sprache mit dem Stack und Heap umgeht.

    btw, auch die Grunddatentypen in C# _sind_ Objekte. Das Konzept von PODs wie in z.B. C++ gibts hier nicht.



  • Ja stimmt, das meinte ich eigentlich. Aber meine Frage ist nun, wie werden die Value Types auf dem Stack angesprochen? Der kann ja nur mittels push und pop (macht sicher jede Sprache so) benutzt werden und nicht durch direkte Adressierung?
    Bei Übergabe an Funktionen ist klar da werden Werttypen auf den Stack gepusht und bei References nur die Adresse.



  • C. M. Obrecht schrieb:

    Ja stimmt, das meinte ich eigentlich. Aber meine Frage ist nun, wie werden die Value Types auf dem Stack angesprochen? Der kann ja nur mittels push und pop (macht sicher jede Sprache so) benutzt werden und nicht durch direkte Adressierung?

    Natürlich kann man jede Adresse im Speicher auch direkt adressieren.



  • int x = 5;   // legt eine Variable auf dem Stack an auf die man Zugreifen kann
    test(x); // übergibt die Variable an die Funktion
    
    void test(int y)
    {
    
    }
    

    Wo genau ist jetzt das Verständnisproblem?



  • loks schrieb:

    Value Type werden auf dem Stack angelegt, Reference Types auf dem Heap.

    Prinzipiell richtig, aber ergänzend muss man beachten dass es den Fall gibt dass Value Types Member von Reference Types sind und dann werden auch die Value Types aufm Heap angelegt.



  • Vielen Dank;
    werden die Value Types nun auf dem Stack angelegt und z.B. mit

    mov exX, [BP+X]
    

    angesprochen (um auf den Stack zuzugreifen ohne pop/push) oder werden sie mit

    x dd ?
    

    angelegt (für int) und auf den Stack nur gebracht bei einer Übergabe an eine Methode?
    Ganz kurz, was ich hauptsächlich wissen wollte, der Stack von dem bei C# die Rede ist ist der Selbe wie bei Assembler?



  • Bring Assembler nicht mit dem Callstack einer Hochsprache durcheinander. Sicherlich werden die Rücksprungadressen gestapelt, aber nicht einfach nur diese Adressen, sondern dazwischen werden noch die lokalen Variablen (Wertetypen) gespeichert, welche normal adressiert werden können.
    Hier ist eine Abbildung:
    http://en.wikipedia.org/wiki/Call_stack



  • Ach so, man spricht da vom Call-Stack und der ist nicht das Selbe. Alles klar! Das überlegte ich mir eben.


Log in to reply