Parameterübergabe an Unterprogramme

Gast #165814
Ich versuchete das Beispielprogramm "Parameterübergabe an
Unterprogramme" aus dem AVR-Tutorial 3. Der Stack zu realisieren. Nur
leider habe ich die Stelle an der der Zeiger Z auf das letzte freie
Byte im Stack zeigen soll nicht hinbekommen.
Der Wert den der Stack-Pointer tatsächlich hat wird nicht richtig von
dem Z-Pointer übernommen. Kann mir bitte jemand das Programm
korregieren?
Angehängte Dateien:
Gast #165815
An der Stelle, an der Z auf das aktuelle Stackelement zeigen soll,
müsste es

IN ZH, SPH
IN ZL, SPL

heißen. An der Stelle, an der Du den Z-Pointer um 6 inkrementierst,
wäre

ADIW ZH:ZL, 6

sinnvoller.
Gast #165816
Die Parameterübergabe mit Stack sollte man aber nur im äußersten Notfall
machen.

In der Regel ist nämlich die Übergabe in Registern schneller,
Codesparender und Nervenschonender.

Nichts ist häßlicher als ein unbalancierter Stack und oft sauschwer die
faule Stelle zu finden.

Stackfehler wirken sich nämlich immer an einer Stelle aus, die vom
eigentlichen Fehler möglichst weit entfernt liegt.


Peter
Gast #165817
Danke für die hilfe, ich habe gleichzeitig einen zweiten Fehler
entdeckt. Der Pointer muss um 8 inkrementiert werden.
In dem Tutorial wird die Parameterübergabe als eine Möglichkeit
aufgezeig um Unterprogramme flexibler zu machen. Ich habe noch keine
Erfahrung mit dieser Programiersprache und kann dieses nicht
beurteilen.
Angehängte Dateien:
Gast #165818
Traue dem Tutorial.

Sobald Unterprogramme etwas verschachtelt sind, kannst Du nur so
Übersicht bewahren (Rekursionen gehen ohnehin nicht anders). Du mußt
nur innerhalb des Unterprogramms darauf achten, den Stack richtig zu
hinterlassen; das ist nicht wirklich ein Problem.

Peter hat zwar recht, daß sich mit Registerübergabe ein paar Takte
sparen lassen, aber man muß notwendigerweise an mehreren Stellen
dieselben Register für die Übergabe benutzen ... behalte da mal den
Überblick!
Gast #165819
"Sobald Unterprogramme etwas verschachtelt sind, kannst Du nur so
Übersicht bewahren"

Da ist überhaupt kein Unterschied !

Egal ob Stack oder Register, man muß sich erstmal einige Konventionen
überlegen und diese dann einhalten.

Z.B. definiere ich mir Register A3..A0,B3..B0,T3..T0,I1,I0.
A,B sind dann für die Operanden und Rückgabewerte, T,I für temporäre
Variablen und Scheifenzähler.
Schau Dir einfach mal einige Beispiele von mir in der Codesammlung an.

Ich gebe zu, das ist nicht auf meinem Mist gewachsen, ich habs mir
einfach von C-Compilern abgeguckt.

Als ich angefangen habe, habe ich auch wie wild gepusht und gepopt, bis
ich schließlich die Übersicht verloren hatte.
Und dann die vielen Fälle, wo ich mir nen Wolf gesucht habe, nur weil
irgendwo andersrum gepopt als gepusht wurde:

push r16
push r17
push r18
push r19
; mache was
pop r19
pop r17
pop r18
pop r16


Register sind dazu da, um sie zu benutzen und nicht ständig zu pushen.

Natürlich kann man sich einige Register für sehr häufige globale
Variablen freihalten, aber deshalb hat man ja auch 32 Stück.

Und auch für Interrupts reserviert man ein paar Register.
Z.B. hat man ja 3 Pointer (X,Y,Z), benötigt aber höchstens 2
gleichzeitig. Also ist es eine gute Idee, X nur für Interrupts zu
reservieren. Und da Interrupt fast immer das SREG zerstören, kann man
R2 fest für das Sichern des SREG reservieren.


"Rekursionen gehen ohnehin nicht anders"

Rekursionen sollte man als Anfänger meiden, wie der Teufel das
Weihwasser. Typisch für Rekursionen ist nämlich, daß sie bei
ungünstigen Startwerten sehr gerne zum Stacküberlauf führen.

Nur erfahrene Programmierer können da die Übersicht behalten (aber die
benutzen in der Regel C).

Für den Anfänger sind Schleifen statt Rekursionen wesentlich
übersichtlicher, schneller und vor allem sicherer.


Peter

Antwort schreiben

Eine eigene Frage? Dieser Thread ist über 21 Jahre alt. Stell sie in einem eigenen Thread – dort lesen mehr Leute mit, und sie wird öfter und schneller beantwortet.

Neuen Thread starten

Eine Lösung, Ergänzung oder Rückmeldung zu diesem Thread? Dann antworte hier.

Formatierung
  • [c]C-Code[/c]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] – Link zu einem Artikel
  • Verweis auf einen anderen Beitrag: Rechtsklick auf dessen Beitrags-ID (#8078628), „Adresse kopieren“, in den Text einfügen

Mehr zur Formatierung

Längeren Sourcecode als Anhang, nicht in den Text. JPG nur für Fotos und Scans; Zeichnungen und Screenshots als PNG oder GIF. Siehe Bildformate.

Schon registriert? Anmelden

Wird nicht angezeigt. Wir schicken dir einen Link; sobald du damit bestätigst, erscheint dein Beitrag.

Mit dem Abschicken legst du einen kostenlosen Account an und erkennst die Nutzungsbedingungen und die Datenschutzerklärung an.