Guten Nachmittag, ich programmiere gerade einen ATTiny2313 in Assembler. cp register1, register2 BRNE Unterprogramm // if(register1 != register2) Unterprogramm(); ich möchte nun das Unterprogramm mit "RET" beenden, dazu brauche ich vorher die Rücksprungadresse auf dem Stack da die bei BRNE nicht automatisch gesetzt wird. Wie stell ich das am Besten an?
:
Bearbeitet durch User
Benjamin S. schrieb: > Wie stell ich das am Besten an? einfach call verwenden, und sonst mit BR* über denn call springen.
Ja so habe ich es nun gelöst: BREQ UnterprogrammJMP rcall Unterprogramm UnterprogrammJMP:
Benjamin S. schrieb: > Wie stell ich das am Besten an?
1 | cp register1, register2 |
2 | BREQ KeinUnterprogramm |
3 | call Unterprogramm; |
4 | KeinUnterprogramm: |
So ein Gebastel, wie du es machen willst, holt dich früher oder später ein... EDIT: Zweiter... ;-)
:
Bearbeitet durch Moderator
In einem Unterprogramm ist das Praktisch nicht möglich! Der Sinn ein Unterprogramm zu schreiben liegt ja darin, es von verschiedenen Stellen aus aufzurufen. Somit weis Dein Unterprogramm auch nicht wohin es zurückspringen soll. Oder anders ausgedrückt woher es gekommen ist. Was aber gehen sollte ist, vor jedem Aufruf den Programmzähler in ein Register zu laden, der Wert um die nötige Anzahl an Schritten zu erhöhen und auf dem Stack abzulegen. Eine Sequenz hierfür würde dann folgendermaßen aussehen: Hole PC low Hole PC high Erhöhe PC(H):PC(L) um die entsprechende Anzahl an Schritten Push PC Push PC JMP Unterprogramm :XXXX ist die Rücksprungadresse. Du kannst die Rücksprungadresse auch "manuell" ermitteln, indem Du ein Label erzeugst. Das geht aber nur, wenn Du die jeweils passende Rücksprungadresse auf dem Stapel ablegst. Um das Ganze etwas weniger Fehlerabfällig zu machen, solltest Du den UP-Aufruf in ein Makro verpacken.
meinst du so etwas?
1 | cpse register1,register2 |
2 | rcall unterprogramm |
3 | ... |
Bei Devices bis 128 KiB Flash, also 2-Byte PC: 1) Untere 8 Bit der Word-Adresse auf den Stack 2) Obere 8 Bit der Word-Adresse auf den Stack 3) RET Sinnvoll ist das aber bestennfalls in einem OS o.ä. oder für einen indirekten Sprung // CALL falls IJMP // ICALL nicht verwendbar sind weil z.B. im Z-Register ein Parameter übergeben werden soll.
:
Bearbeitet durch User
Benjamin S. schrieb: > Ja so habe ich es nun gelöst: > BREQ UnterprogrammJMP > rcall Unterprogramm > UnterprogrammJMP: Besser: cpse Reg1,Reg2 rcall Unterprogramm Spart das Ausdenken eines Bezeichner für ein Sprungziel und (viel wichtiger) einen nutzlos verschwendeten Takt...
Richard H. schrieb: >> Manuel auf den Stack legen > > Wer ist Manuel? Eigentlich wäre es doch das Erste, Manuel zu fragen, ob er überhaupt fremde Adressen auf seinem Stack abgelegt haben will. Ich würde das nicht wollen...
c-hater schrieb: > Besser: > > cpse Reg1,Reg2 > rcall Unterprogramm So sehe ich das auch, siehe 15:09 > Spart das Ausdenken eines Bezeichner für ein Sprungziel und (viel > wichtiger) einen nutzlos verschwendeten Takt... ... und ein Befehlswort im Programmspeicher.
Eberhard H. schrieb: > So sehe ich das auch, siehe 15:09 Ja, da habe ich den Thread wohl zu schnell durchgescrollt.
Hi Eberhard H. schrieb: > meinst du so etwas? > cpse register1,register2 > rcall unterprogramm > ... Verdammt - Der Gedanke kam mir auch gerade - schon beim Durchsuchen der Befehlsliste (überflogen nach 'Skip') sah ich aber, daß Ihr Den Gedanken schon weit vor mir hattet :) MfG
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.