allgemeine (Anfänger-)Fragen zu Heap und Stack



  • Würd_gern_C_können schrieb:

    Ok, also steht in dem Stack-Register nur die Adresse des Stacks. Hab ich das richtig verstanden, dass die Größe vom Stack vordefiniert ist (vom OS)?

    Nein ist sie nicht, die kannst du "frei" wählen und so hoch setzen wie dein Prozessor adressieren kann.

    TheTester schrieb:

    Dass ist auch durch die Größe bedingt die ist oft recht klein gewählt ein paar MB oder sogar nur 1MB, das unterstreicht auch den Verwendungszweck des Stacks. Jedenfalls kann der Stack aber bis 4GB groß sein unter IA-32.
    tt

    Würd_gern_C_können schrieb:

    Dann liegt im Stack-Register auch noch die "End-Adresse" vom Stack? Und wenn ich das Ende vom Stack irgendwann mal überschreiten sollte, ist das dann auch ein Buffer-Overflow? Und was passiert dann?

    Nein, die liegen für gewöhnlich in den Globalen und Lokalen Descriptor Tables. Und wenn es die End-Adresse erreicht sollte eine Exception vom Prozessor auftreten und dein Programm wird für gewöhnlich abstürzen. Beim Stack nennt man das dann Stackoverflow.



  • Würd_gern_C_können schrieb:

    Dann liegt im Stack-Register auch noch die "End-Adresse" vom Stack? Und wenn ich das Ende vom Stack irgendwann mal überschreiten sollte, ist das dann auch ein Buffer-Overflow? Und was passiert dann?

    so etwas in der Art. Es ist eigentlich eine Aufgabe des Kernels, Stacksoverflows zu verhindern und darauf zu reagieren, meinstens durch eine Exception. Aber das ist Architektur abhänhig, d.h. jede Architektur hat da seine Tricks, mit denen man solche Sachen überpfüfen kann.



  • vista schrieb:

    der stack-pointer ist einfach nur ein zeiger. wenn sein wertebereich um 1 überschritten wird, steht der wieder auf 0. und umgekehrt, ist er 0 und man führt einen POP- oder RET-befehl aus, dann dann hat er plötzlich einen irre hohen wert.

    Du meinst vermutlich push und call. Der Stack Pointer arbeitet absteigend, dh immer wenn etwas auf dem Stack gespeichert wird, wird er verringert.



  • groovemaster schrieb:

    vista schrieb:

    der stack-pointer ist einfach nur ein zeiger. wenn sein wertebereich um 1 überschritten wird, steht der wieder auf 0. und umgekehrt, ist er 0 und man führt einen POP- oder RET-befehl aus, dann dann hat er plötzlich einen irre hohen wert.

    Du meinst vermutlich push und call. Der Stack Pointer arbeitet absteigend, dh immer wenn etwas auf dem Stack gespeichert wird, wird er verringert.

    stimmt. bei vielen prozessoren arbeitet der stack tatsächlich rückwärts.
    weiss eigentlich jemand warum das so ist?



  • vista schrieb:

    groovemaster schrieb:

    vista schrieb:

    der stack-pointer ist einfach nur ein zeiger. wenn sein wertebereich um 1 überschritten wird, steht der wieder auf 0. und umgekehrt, ist er 0 und man führt einen POP- oder RET-befehl aus, dann dann hat er plötzlich einen irre hohen wert.

    Du meinst vermutlich push und call. Der Stack Pointer arbeitet absteigend, dh immer wenn etwas auf dem Stack gespeichert wird, wird er verringert.

    stimmt. bei vielen prozessoren arbeitet der stack tatsächlich rückwärts.
    weiss eigentlich jemand warum das so ist?

    Tja vielleicht eine Frage der "Sichtweise", das Wort sollte ja vom lateinischen Wort für "Kammer" abstammen. Wenn du was in eine Kammer reinstellst fängst du ja auch am Ende an und dann stellst du mehr Zeug in deiner Richtung rein.
    Wenn du dann also z.B. jetzt die Länge der Kammer nimmst und jeder Zentimeter eine Adresse darstellt dann fängst du bei der höchstmöglichen Adresse an und je mehr du reinstellst desto kleiner werden die Adressen. 😃

    Also praktisch wenn du auf einen Stack (Tellerstapel oder ähnliches) draufschaust dann "wächst" er zu dir und wenn du ein Element rausnimmst verkleinert er sich "weg" von dir. *schmunzl*.

    Aber so gesehen, keine Ahnung 😃

    tt



  • vista schrieb:

    stimmt. bei vielen prozessoren arbeitet der stack tatsächlich rückwärts.
    weiss eigentlich jemand warum das so ist?

    Der Heap wächst aufwärts und der Stack abwärts. Solange sie sich nicht in der Mitte treffen ist alles in Butter ...
    Jedenfalls war das früher mal so, ob das heute auch noch so ist oder ob sich die beiden nicht mehr in die Quere kommen können weiß ich nicht.



  • Bashar schrieb:

    Der Heap wächst aufwärts und der Stack abwärts. Solange sie sich nicht in der Mitte treffen ist alles in Butter ...
    Jedenfalls war das früher mal so, ob das heute auch noch so ist oder ob sich die beiden nicht mehr in die Quere kommen können weiß ich nicht.

    Ich bin mir nicht ganz sicher ob man dass als Grund angeben kann. Wenn ich mich recht entsinne liegt z.B. bei Linux der Stack "vor" dem Heap und wächst Richtung Heap und der Heap in Richtung Stack.
    Wobei ist es überhaupt relevant bei Systemen mit "segmentbasierter" Speicherverwaltung? Da müssen ja nur die Segmentstartadressen so gelegt sein das der Stack z.B. weit genug "davor" liegt.

    Bei Windows (XP) bin ich mir übrigens gar nicht so sicher wo der Heap liegt, dort scheint es so als ob Code, Text usw. "zwischen" Stack und Heap liegt, die beiden sich also sowieso nicht "sehen".

    tt



  • http://chaosradio.ccc.de/media/video/der_stack.m4v

    Das wird alle eure Fragen erklären. Grade bei Wikipedia gefunden. Könnte eventuell da einer rausnehmen, ist ja nichts informatives. Naja deie Leute da haben auch offensichltich keine Ahnung.

    Und das ganze Stack/Heap-Gelaber könnt ihr euch eigentlich sparen, ist alles von der Platform abhängig. Wenn ich mit eurer x86 Diskussion fertig seid, fang ich mit meinem AVR an.



  • Uiuiui, da programmiert einer AVRs *verneig*



  • TheTester schrieb:

    Bei Windows (XP) bin ich mir übrigens gar nicht so sicher wo der Heap liegt, dort scheint es so als ob Code, Text usw. "zwischen" Stack und Heap liegt, die beiden sich also sowieso nicht "sehen".

    unter xp hat jeder thread seinen eigenen stack und jeder prozess bekommt einen heap zugeteilt, den sich alle threads teilen können. weil xp sowieso mit virtuellen adressen arbeitet, kann der speicher dafür 'irgendwo' sein. der stackpointer 'wächst' aber trotzdem nach unten. warum?

    Entenwickler schrieb:

    Und das ganze Stack/Heap-Gelaber könnt ihr euch eigentlich sparen, ist alles von der Platform abhängig. Wenn ich mit eurer x86 Diskussion fertig seid, fang ich mit meinem AVR an.

    die kleinen avr's haben nur einen 8bit stackpointer, die grösseren 16bits. bei beiden sollte bei der initialisierung der SP auf die höchste adresse des internen RAMs gesetzt werden d.h. der stack zählt auch abwärts. warum nur?

    btw: beim ollen 6502 hatte der stack einen festen bereich zwichen 0x100 und 0x1ff. auch hier: initialisierung mit 0x1ff und dann geht's runter bei PUSHes und CALLs. merkwürdig, nicht?



  • Ich hab auch nicht bezweifelt, dass er hier nicht nach unten (oben / unten im Sinne von Speicheradresse) wächst. Wobei ein Stack grundsätzlich auch nach oben wachsen könnte.

    Ich spielte auf die Diskussion an wo der Stack bzw. der Heap jeweils platziert ist. Und das kann ich beim Programmieren in C nicht* bestimmen. Es kann mir auch völlig egal sein ob mein Compiler noch ein Datensegment drauf packt, es kann mir egal sein wo der Heap ist, und es kann mir egal sein wie das Betreibsystem den Speicher verwaltet.

    😉 Klar gerade bei Mikroprozessoren kann man es bestimmen, mir hat es immer genügend den Compiler das alles entscheiden zu lassen. Wozu nehme ich schließlich eine Hochsprache wie C?



  • Entenwickler schrieb:

    ...mir hat es immer genügend den Compiler das alles entscheiden zu lassen.

    irgendwann reicht das nicht mehr. wirste schon merken 😉



  • vista schrieb:

    der stackpointer 'wächst' aber trotzdem nach unten. warum?

    Wie ich schon sagte, aus historischen Gründen. Ob das heute unter Windows oder Linux noch eine Rolle spielt, sei mal dahingestellt, vermutlich nicht. Aber die Semantik von Push/Pop/Call/Ret ändert man nicht mal einfach so innerhalb einer Prozessorarchitektur ...


Anmelden zum Antworten