Wenn mir die Register ausgehen, greife ich selbstverständlich zum Stack, wo würde es aber Sinn mach die Daten über LDS/STS in den SRAM abzulegen? Nehmen wir mal als Beispiel ein Bild (32*32 Pixel), welches dekomprimiert werden soll. Würde man das mit dem Stack lösen oder nicht?
Das ist wie lernn du überlegst, ob du die Rechnung aus der inken oder rechten Hosentasche bezahlst. Denn der Stack ist ein Teil des SRAM: je größer der Stack umso weniger RAM bleibt über...
Beitrag #5676916 wurde vom Autor gelöscht.
Lothar M. schrieb: > Denn der Stack ist ein Teil des SRAM: je > größer der Stack umso weniger RAM bleibt über... Du hast mich falsch verstanden, ich weiß das natürlich. Wenn ich ich es richtig verstanden habe, spielt es keine Rolle ob push oder STS und pop oder LDS.
Laie Jonas schrieb: > Du hast mich falsch verstanden, ich weiß das natürlich. Mit push und pop ist die Reihenfolge zwingend vorgegeben. Deshalb wird ein Compiler auch für Operationen "auf dem Stack" die üblichen wahlfreien Speicherzugriffe verwenden. Er muss nur den Stackpointer richtig manipulieren. Wenn er auf den Stackpointer 32x32 draufaddiert, dann hat das ganze Array problemlos Platz. > Wenn ich ich es richtig verstanden habe, spielt es keine Rolle ob push > oder STS und pop oder LDS. Kommt auf den Prozessor an... ? Aber üblicherweise ändert ein Zugriff über andere Pointer den Stackpointer nicht. Insofern spielt da schon irgendwas irgendeine andere Rolle.
:
Bearbeitet durch Moderator
Laie Jonas schrieb: > Wenn mir die Register ausgehen, greife ich selbstverständlich zum Stack, > wo würde es aber Sinn mach die Daten über LDS/STS in den SRAM abzulegen? > > Nehmen wir mal als Beispiel ein Bild (32*32 Pixel), welches > dekomprimiert werden soll. > Würde man das mit dem Stack lösen oder nicht? Wenn du die Pixel nachher in genau der umgekehrten Reihenfolge wieder lesen willst und nach dem einen Lesevorgang nicht mehr brauchst, kannst du push/pop nehmen. Sonst kommst du um LDS/STS und Konsorten nicht rum.
Laie Jonas schrieb: > greife ich selbstverständlich zum Stack, > wo würde es aber Sinn mach die Daten über LDS/STS in den SRAM abzulegen? Das kommt im wesentlichen auf die benötigte Lebensdauer an: Daten im RAM bestehen ewig oder bis man den Speicher bewusst freigibt, Daten auf dem Stack sind nur solange verfügbar wie das aufgerufene Unterprogramm läuft, mit dem Returnbefehl sind sie verschwunden. Georg
Laie Jonas schrieb: > Wenn mir die Register ausgehen, greife ich selbstverständlich zum Stack, > wo würde es aber Sinn mach die Daten über LDS/STS in den SRAM abzulegen? Aha. Du bist Assembler-Programmierer. Andere Programmiersprachen wie z.B. C organisieren das gleich mit für dich; lokale Variablen auf dem Stack, globale im Datensegment. Und wieder andere wie Forth verwenden für alles den Stack. > Nehmen wir mal als Beispiel ein Bild (32*32 Pixel), welches > dekomprimiert werden soll. > Würde man das mit dem Stack lösen oder nicht? Kommt drauf an. Der Stack bringt nur/vor allem dann etwas, wenn du das spezielle Zugriffsmuster (LIFO - last in, first out) ausnutzen kannst. Um einen Stream zeichenweise zu lesen, ist der Stack schon ganz gut geeignet. Die Frage ist, ob die Daten vorher auch in umgekehrter Reihenfolge reingekommen sind. Weil wenn nicht, dann bringt der der Stack gar nichts. Dann kannst du auch gleich mit dem Z-Pointer und pre/post Increment arbeiten. Wenn auf das Bild dann vielleicht gar noch wahlfrei zugegriffen werden muß, z.B. einmal zeilen- und einmal spaltenweise, dann ist endgültig Essig mit Stack.
Laie Jonas schrieb: > Wenn mir die Register ausgehen, greife ich selbstverständlich zum Stack, Nö, das ist nur eine Möglichkeit. Auf dem Stack werden im Normalfall nur lokale Variablen von Funktionen platziert. > wo würde es aber Sinn mach die Daten über LDS/STS in den SRAM abzulegen? Überall, sowohl auf dem Stack als auch auf dem Heap. > Nehmen wir mal als Beispiel ein Bild (32*32 Pixel), welches > dekomprimiert werden soll. > Würde man das mit dem Stack lösen Kann man machen, muß man aber nicht. Das hat aber mit lds/sts bzw. push und pop (wir reden hier von AVR Assembler) wenig bis nix zu tun. Denn push/pop werden praktisch nur am Anfang und Ende einer Funktion benutzt, um diverse Register auf dem Stack zu sichern. Der Zugriff auf lokale, temporäre Variablen auf dem Steck erfolgt per ld(d)/st(d) mit relativer Adressierung. lds/sts sind beim AVR Zugriffe mit absoluter Adressierung und damit logischerweise nur für konstante Adressen von globalen oder lokal statischen Veriablen verwendbar.
Laie Jonas schrieb: > Wenn mir die Register ausgehen, greife ich selbstverständlich zum Stack, > wo würde es aber Sinn mach die Daten über LDS/STS in den SRAM abzulegen? Angenommen: Zielarchitektur sei AVR8 (nein, für Voll-Dummies: das ist keinesfalls selbsverständlich, gehört also bei so einer Frage zumindest erwähnt!) Beim AVR8 jedenfalls spielt es prinzipiell erstmal keine Rolle. Push/pop kostet genauso zwei Takte wie lds/sts. Hier wäre der Algorithmus relevant. Wenn dieser mit so einem einfachen FILO-Speicher wie dem Stack auskommt, dann nimmt man natürlich auch den Stack. Ansonsten eher über die Index-Register indirekt (ggf. mit Offset) adressierten RAM. Dafür wäre dann allerdings wiederum nicht lds/sts zu verwenden, sondern ld/st oder ldd/std. Sprich: nur dann, wenn es sowieso nur um ein einzelnes Datum ging, ergibt deine Frage irgendeinen Sinn. Und die korrekte Antwort für diesen speziellen Fall ist: es ist scheißegal.
c-hater schrieb: > relevant. Wenn dieser mit so einem einfachen FILO-Speicher wie dem Stack > auskommt, dann nimmt man natürlich auch den Stack. Gebräuchliche Abkürzung dafür ist LIFO. Das ergibt nur dann einen Sinn wenn keine Interrupts zu erwarten sind. Auch darf diese Routine selbst keine Unterprogramme aufrufen. > Ansonsten eher über > die Index-Register indirekt (ggf. mit Offset) adressierten RAM. Ja, das ist am übersichtlichen, aber natürlich vorher die Hilfsregister als Konstanten deklarieren, etwa so:
1 | .equ c_RegA = 0 |
2 | .equ c_RegB = 1 |
3 | ...
|
4 | .equ c_RegZ = 24 |
Marc V. schrieb: > Das ergibt nur dann einen Sinn wenn keine Interrupts zu erwarten sind. > Auch darf diese Routine selbst keine Unterprogramme aufrufen. Wieso sollte das so sein? Nach Ausführung einer ISR oder eines Unterprogramms befindet der Stack sich typischerweise wieder in genau dem Zustand, den er vorher auch hatte. Es ist also für den Aufrufer des Unterprogramms oder das "unfreiwillig" unterbrochene Programm (bezogen auf den Stack) so, als wäre überhaupt nix passiert. Ja, natürlich kann man das ändern, sowohl bei einer ISR als auch bei einem "normalen" Unterprogramm. Wird man aber typischerweise eher nicht tun. Ziemlich sicher jedenfalls nicht beim AVR8, da ergeben explizite Stack-Manipulationen nur sehr selten irgendeinen Sinn, schlicht weil sie (im Vergleich zu den sonstigen Möglichkeiten) vergleichweise langsam sind.
Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.