Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » C / C++ (ANSI-Standard) » Der Gottverdammte Stackspeicher

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ]
020
03.08.2005, 12:02 Uhr
(un)wissender
Niveauwart


@Tommix
Wenn du recht haben willst,ok, hier ist das Recht.
Wir bezogen uns halt hier schon direkt auf virtuelle Adressen, und da sieht man dann doch bei den meisten Systemen, dass man was an den Stack anhängt und nicht wirklich drauftut, auch wenn der Befehl push oder so heißt. Wenn man nicht selbst am Stack bauen will oder ihn wirklich verstehen möchte, ist der Unterschied aber egal, da gebe ich dir recht.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
021
03.08.2005, 12:58 Uhr
virtual
Sexiest Bit alive
(Operator)


@(un)wissender
In logischer Hinsicht wächst der Stack so wie ich sagte. Man kann Deiner Aussage höchstens auf ein bestimmtes Betriebsystem auslegen: Die x86 Familie von Intel, insbesondere ab 80286 verwalten zu den Segmenten ein sog. "Direction-Flag": da kann man einstellen, ob man beim Stack die Adressen wachsen oder fallen lassen will. Ich kenne aber kein BS, welches die Adressen mit den Funktionsaufrufen wachsen liesse.

Die traditionelle Sichtweise ist die, daß man den Stack von großen zu kleinen Adressen wachsen läßt. Dies ist geprägt durch ein Flaches Speichermodell, bei dem der Adressraum eine Prozesses in etwa so aussieht, daß in den niedrigen Adressen der Programm code liegt, gefolgt von Datensegemente, danach Heap und schließlich Stack. Dabei gibt es zwischen Heap und Stack eine Lücke:

Code:
0001.... Programmcode
0003.... Datensegmente
000F.... Heap
...10 ... Frei
00FF ... Stack


(Die Adressen sind jetzt mal aus den Fingern gesaugt, lediglich die Reihenfolge ist von interesse). der Heap wächst indem man malloc o.ä. macht auf den Stack zu, umgekehrt wächst der Stack durch funktionsaufrufe auf den Heap zu. Diese Speicherlayout wird nach wie vor noch bei Linux verwendet, wenngleich die Bereiche in verschiedenen Segmenten liegen und - wie du selbst bemerkst - einfach virtuell umgeblendet werden.
Und schau dir bitte mal dieses auf einem Intel ausgeführte Progrämmchen an:

C++:
#include <stdio.h>

void print_stack_pointer(int level) {
    printf("Level %d: %p\n", level, &level);
    if (level>1) print_stack_pointer(level-1);
}

int main() {
    print_stack_pointer(5);
}


Ausgabe unter Linux:

Code:
Level 5: 0xbffff454
Level 4: 0xbffff434
Level 3: 0xbffff414
Level 2: 0xbffff3f4
Level 1: 0xbffff3d4


Ausgabe unter Windows (mit cygwin compiliert):

Code:
Level 5: 0x22fee0
Level 4: 0x22fec0
Level 3: 0x22fea0
Level 2: 0x22fe80
Level 1: 0x22fe60


In beiden Fällen wächst der Stack zu niedrigen Adressen...
--
Gruß, virtual
Quote of the Month
Ich eß' nur was ein Gesicht hat (Creme 21)
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
022
03.08.2005, 14:11 Uhr
(un)wissender
Niveauwart


Jo, nichts anderes habe ich ja gesagt.
Aus logischers Sicht ist das natürlich so einen Sache, kommt nämlich immer drauf an, welche Logik man gerade meint.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
023
03.08.2005, 14:13 Uhr
kanonenvirus



also ist die 0x22fe60 die grössere adresse(da wo level 1 steht ) oder was und 0x22fee0(Level 5) die kleinere oder wie (zu binären Zahlencodes etc. wird erst am Ende des Buches stellung genommen).
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
024
03.08.2005, 14:52 Uhr
Tommix




Zitat von kanonenvirus:

95.
96.
97.
98. Variable 3
99. Variable 2
100. Variable 1


So sieht's aus. Wobei die Nummern (Adressen) auch andersherum geordnet sein könnten. Es wäre dann immer noch ein Stack. Mach Dir da nicht zuviele Gedanken.

- Tommix

(@all: Er ist bei Tag 5 von 21. Viel Spaß, wenn er bei der Mehrfachvererbung angekommen ist. )
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
025
03.08.2005, 14:55 Uhr
kanonenvirus



ok dann habe ich die letzte frage an euch. Dazu aber ein kleines Programmchen wa sich schon vorher angegeben hab.

C++:
#include <iostream.h>

int main2(int, int);

int main()
{
int x = 50, y = 70;
main2(x,y);
return 0;
}

itn main2(int x, int y)
{
int z = 80;
return (x + y + z);
}


Und hier ist eine Stelle aus meinem Buch die mich etwas verwirrt. Es handelt sich hierbei um den Stack und sene Datenstruktur wenn man in eine andere Funktion verzweigt. Die Schritte sind folgende:
Stack und Funktionen
Wenn ein Programm, das auf einem PC unter DOS ausgeführt wird, in eine Funktion verzweigt, passiert folgendes:

1.)Die Adresse im Befehlszeiger wird inkrementiert zu der nächsten Anweisung nach dem Funktionsaufruf. Diese Adresse wird dann auf dem Stack abgelegt und bildet damit die Rückkehradresse für die Funktion, wenn sie zurückkehrt.
2.)Auf dem Stack wird Platz für den von Ihnen deklarierten Rückgabetyp geschaffen. Bei einem System mit 2-Byte-Integers werden im Falle eines als Integer deklarierten Rückgabetyps zwei weitere Bytes dem Stack hinzugefügt. In diesen Bytes wird kein Wert abgelegt.
3.)Die Adresse der aufgerufenen Funktion, die in einem speziellen dafür vorgesehenen Speicherbereich abgelegt wurde, wird in den Befehlszeiger geladen, so daß die nächste ausgeführte Anweisung sich in der aufgerufenen Funktion befindet.
4.)Die aktuelle Spitze des Stacks wird jetzt festgehalten und in einem speziellen Zeiger, dem Stack-Rahmen, abgelegt. Alles, was von jetzt an dem Stack hinzugefügt wird, bis die Funktion zurückkehrt, wird als »lokal« zur Funktion betrachtet.
5.)Alle Argumente an die Funktion werden auf dem Stack plaziert.
Die jetzt im Befehlszeiger befindliche Anweisung, das heißt, die erste Anweisung in der Funktion, wird ausgeführt.
6.)Die Funktion legt die in ihr definierten lokalen Variablen auf dem Stack ab.

Ist die Funktion soweit, zurückzukehren, wird der Rückgabewert in dem in Punkt 2 beschriebenen Stack-Bereich abgelegt. Der Stack wird jetzt bis zum Stack-Rahmen-Zeiger aufgelöst, so daß damit alle lokalen Variablen und die Argumente der Funktion entfernt werden.

Der Rückgabewert wird vom Stack geschmissen und als Wert des Funktionsaufrufs zugewiesen. Die in Punkt 1 gespeicherte Adresse wird ermittelt und im Befehlszeiger abgelegt. Das Programm fährt deshalb direkt nach dem Funktionsaufruf mit dem Rückgabewert der Funktion fort.

Einige Details dieser Vorgehensweise sind von Compiler zu Compiler oder unter Computern verschieden, aber die wesentlichen Konzepte sind umgebungsunabhängig. Allgemein gilt, daß Sie bei Aufruf einer Funktion die Rückgabeadresse und die Parameter auf dem Stack ablegen. Solange die Funktion »lebt«, werden die lokalen Variablen dem Stack hinzugefügt. Kehrt die Funktion zurück, werden sie entfernt, indem der Stackbereich der Funktion aufgelöst wird.


Wenn ich dazu meinen Code nehme und die Schritte durchführe dann würde das ungefähr so auf em Stapel aussehen.



48.. variable
49.. Argument
50.. Rückkehradresse

Wenn Ihr es besser wisst erklärt mir die schritte deutlicher dankee.

mod edit: wieso benutzt keiner die CPP Tags selber?

Dieser Post wurde am 03.08.2005 um 19:52 Uhr von Pablo editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
026
03.08.2005, 22:32 Uhr
~Nur mal so
Gast


Ich finde eure Beiträge in diesem Forum echt immer interessant, besonders die von Virtual.
Deshalb hier noch mal ein paar Anmerkungen.


Zitat:

In logischer Hinsicht wächst der Stack so wie ich sagte. Man kann Deiner Aussage höchstens auf ein bestimmtes Betriebsystem auslegen: Die x86 Familie von Intel, insbesondere ab 80286 verwalten zu den Segmenten ein sog. "Direction-Flag": da kann man einstellen, ob man beim Stack die Adressen wachsen oder fallen lassen will. Ich kenne aber kein BS, welches die Adressen mit den Funktionsaufrufen wachsen liesse.



Ist die x86 Familie von Intel ein Betriebsystem, oder habe ich vielleicht irgendwann mal irgendwas falsch verstanden?
Ob der Stack von oben nach unten oder von unten nach oben wächst hängt doch nur vom verwendeten Prozessor ab.
Oder jemand macht sich die Mühe, den Prozessor per Software zu emulieren.

Nur mal so
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
027
03.08.2005, 23:08 Uhr
(un)wissender
Niveauwart


Ja, virtual ist schon ein guter.
x86 ist eine Hardwarearchitektur, wobei x86 alles vom 8086 bis zum P4 meint.
--
Wer früher stirbt ist länger tot.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
028
03.08.2005, 23:11 Uhr
Windalf
Der wo fast so viele Posts wie FloSoft...
(Operator)



Zitat:

wobei x86 alles vom 8086 bis zum P4 meint


P4? Wie kann hier eigentlich eine Student von Intel reden? Du meinst AMDs oder?
--
...fleißig wie zwei Weißbrote
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
029
04.08.2005, 01:43 Uhr
kanonenvirus



hallo es ist auf eine funktionsverzweigung unter MSDOS . Also bekomme ich meine Antwort auf den obersten text. Ich meine der Text aus dem Buch.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: [ 1 ] [ 2 ] > 3 < [ 4 ]     [ C / C++ (ANSI-Standard) ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: