mikrocontroller.net

Forum: Mikrocontroller und Digitale Elektronik Branch rücksprung


Autor: Benjamin Böck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Mal ne Frage zum Verständniss

Der Brunch Befehl speichert keine Rücksrungadresse im Stack?
d.h. ich muß aus einer mit einem Bruch Befehl aufgerufen Sub wieder
durch einen Rücksprung an ein Label zu meiner Aufrufstelle
zurückspringen?

In etwa so
"

 branch Sub
   NachBrunch:



 Sub:
   .....
   .....
   .....
   rjmp NachBrunch

"
oder gibt es da eventuell ne elegantere Lösung, die die
Rücksprungadresse im Stack hinterlegt und mit ret wieder beendet werden
kann?

Autor: Rufus T. Firefly (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Branch = GOTO

(lädt einen neuen PC und fertig)

Warum verwendest Du nicht Call?

Call speichert die Adresse des nächsten Befehles auf dem Stack und lädt
einen neuen PC.

Ret ist die korrekte Antwort auf Call.

Autor: Benjamin Böck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Weil ich nach einen Vergleich eine Bestimmte Aktion ausführen möchte
z.B.

SUBI Temp,0x10
BREQ Sub1
BRMI Sub2

und danch nach dem Vergleich das Programmm weiter abarbeiten.
Aber trotzdem vielen Dank dür deinen Antwort, werde es wohl doch so
machen müssen wie ich es vorhatte.

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Diese elegante Lösung heisst call :) oder acall... und "br*u*nch" ist
ja wohl ganz was anderes ;-)


Das Konstrukt oben ist beliebig gefährlich, weil das eben kein
wirkliches Unterprogramm ist. Rufst du es dann noch einmal von anderer
Stelle aus auf, ist der Ärger vorprogrammiert.

Eine Lösung ist es, den Branch umzudrehen (aus eq wir ne etc...) und
über den Call zur Subroutine hinwegzuspringen, wenn die Bedingung
nicht erfüllt ist.

  branch weiter
  acall  sub
weiter:

Autor: Benjamin Böck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Aber bei mehreren möglichkeiten ist das auch wieder ein ganz schönes
gefrickel.
Allerdings mit dem Vorteil das ich meine Sub aus mehreren stellen im
Prog aufrufen kann und mit ret zurückkomme.
Ist immerhinn schon besser als meine Anfangslösung!!

Autor: Thomas Burkhardt (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Nein, nein, man nennt das nicht Gefrickel, sondern Assembler :)

Es hat halt wirklich den Vorteil, dass die Subs echte Unterprogramme
sind, die sauber dorthin zurückspringen, wo sie herkommen. Wirkliches
Gefrickel wäre, den Rücksprungwert von Hand aufm Stack abzulegen. Eine
Vorgehensweise, die allerdings nicht zu empfehlen ist.

Autor: Benjamin Böck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Hast schon recht. Ich dachte es gibt evntuell ne möglichkeit des Branch
Befehls mit der Rücksprungoption über den Stack.
Die Rücksprungadresse auf dem Stack abzulegen habe ich mir auch schon
überlegt aber bei einem nachträglichen ändern des Source Codes wäre die
Rücksprunadresse jedesmal falsch und diese Fehlerquelle wollte ich mir
nicht aufhalsen ;-)

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
das geht schon, aber ob es in deinem Falle einen Sinn macht ist die
andere Frage. Bei vielen solchen nachfolgenden Abfragen könnte das
schon Sinn machen:


        ldi    r16, 0x11

        ldi    r17,low(return)
        push   r17
        ldi    r17,high(return)
        push   r17

        subi   r16, 0x10
        breq   sub1
        brmi   sub2
        ret

return: nop
        rjmp   return

sub1:   nop
        ret

sub2:   nop
        ret

Funktioniert aber nur auf Devices ohne Hardware-Stack.

Gruß Hagen

Autor: Benjamin Böck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Auch nicht uninteressant.
Du push'st die Adresse der Rücksprungstelle so das du mit RET darauf
zugreifen kannst.
Das ist wohl die sauberste Möglichkeit wieder zurück an die
Aufrufstelle zu kommen.

THX Ben

Autor: Peter Dannegger (peda)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es geht noch einfacher:

my_function:
        ...
        rcall tester
hier_gehts_weiter:
        ...
        ret

tester:
        subi   r16, 0x10
        breq   sub1
        brmi   sub2
        ...
        ret              ;springt nach hier_gehts_weiter

sub1:
        ...
        ret              ;springt nach hier_gehts_weiter

sub2:
        ...
        ret              ;springt nach hier_gehts_weiter


Peter

Autor: Benjamin Böck (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
Es wird immer besser :)

Autor: Hagen (Gast)
Datum:

Bewertung
0 lesenswert
nicht lesenswert
und Peters Vorschlag läuft mit weniger Takten, weniger Codeverbrauch und
ganz wichtig auf Devices mit HW-Stack. Auf alle Fälle sollte man Peters
Methode benutzen.

Gruß Hagen

Antwort schreiben

Die Angabe einer E-Mail-Adresse ist freiwillig. Wenn Sie automatisch per E-Mail über Antworten auf Ihren Beitrag informiert werden möchten, melden Sie sich bitte an.

Wichtige Regeln - erst lesen, dann posten!

  • Groß- und Kleinschreibung verwenden
  • Längeren Sourcecode nicht im Text einfügen, sondern als Dateianhang

Formatierung (mehr Informationen...)

  • [c]C-Code[/c]
  • [avrasm]AVR-Assembler-Code[/avrasm]
  • [code]Code in anderen Sprachen, ASCII-Zeichnungen[/code]
  • [math]Formel in LaTeX-Syntax[/math]
  • [[Titel]] - Link zu Artikel
  • Verweis auf anderen Beitrag einfügen: Rechtsklick auf Beitragstitel,
    "Adresse kopieren", und in den Text einfügen




Bild automatisch verkleinern, falls nötig
Bitte das JPG-Format nur für Fotos und Scans verwenden!
Zeichnungen und Screenshots im PNG- oder
GIF-Format hochladen. Siehe Bildformate.
Hinweis: der ursprüngliche Beitrag ist mehr als 6 Monate alt.
Bitte hier nur auf die ursprüngliche Frage antworten,
für neue Fragen einen neuen Beitrag erstellen.

Mit dem Abschicken bestätigst du, die Nutzungsbedingungen anzuerkennen.