Hallo an alle, Da ich mich langsam mit Assembler anfreunde ;), bin ich nun auf ein Problem gestoßen. Die Sprungweite liegt bei diesen Befehlen bei +-64 Befehlen. Wie kann ich es nun lösen, dass ich über mehr Befehle springen kann?? Eine zusätzliche Spungmarke möchte ich nicht einbauen, da es dann unübersichtlich wird... Ich hoffe man kann das lösen Danke im Voraus mfg Robert
Eher +-64 ROM-Adressen (Worte). Abhilfe kann man nur schaffen, indem man mit dem Branch-Befehl zu einem (r)jmp verzweigt, der nahe genug am Branch steht.
Ach ja: +-64 stimmt genaugenommen nicht ganz. Es sind +64/-63...
Danke erstmal. Ich hab dazu was gefunden:
1 | cpi pattern, 0x04 |
2 | brne PC+2 |
3 | rjmp pattern4 |
Was macht das PC+2 beim brne genau?
@Robert Du wirst um die zusätzliche Marke nicht rumkommen: ... brne M1 ... <zu viele Befehlszeilen> ... M1: ;Sprungweite zu groß Lösung: ... breq M2 ;Logikumkehr für kurzen Sprung rjmp M1 M2:... <zu viele Befehlszeilen> ... M1: ;Sprungweite reicht aus Gruß Reinhard
> Was macht das PC+2 beim brne genau?
Das ist die zusätzliche Sprungmarke
statt PC+2 kannst Du auch folgendes schreiben. PC ist der Programmcounter [avrasm] cpi pattern, 0x04 brne PCplus2_label rjmp pattern4 PCplus2_label: ... [\avrasm]
OK, danke. Was ist der Programm Counter genau? Edit: Gerade Selbst gefunden. Die Adresse im ROM, die gerade abgearbeitet wird.
Solche Konstrukte wie brne PC+2 sind etwas gefährlich: Darin ist nämlich die Sprungweite hardcodiert, d.h. es kommt (in diesem Fall) auf die Länge des nächsten Befehls an, ob der Trick funktioniert, oder nicht. Wenn der Folgebefehl z.B. 3 Byte lang ist, dann springt der brne PC+2 mitten in den nächsten Befehl hinein und was dann passiert sieht man nicht sofort. Der beste Fall wäre noch, wenn das Programm sofort total abstürzt. Ich würde hardcodierte Sprungweiten nur in Assembler-Macros einsetzten und das auch nur, wenn man keine lokale Marken verwenden kann und der Assembler zu doof ist, Symbole zu erzeugen, die man als Sprungmarken werwenden kann.
Wenn der Bubo bubo seinen letzten Absatz etwas erläutern könnte, den habe ich nicht verstanden ('Symbole erzeugen als Sprungmarken' ?). Ich selbst benutze gern und regelmäßig 'go' PC +/- n, und falle regelmäßig auf die Nase bei späteren Programmänderungen oder wenn ich ein lds oder sts übersehen habe. Bequem fände ich eine Möglichkeit, wie sie bei einem Assembler für den HP48 existiert: go + . . . +: ... Verzweige vorwärts zum nächsten '+'; '-' entsprechend rückwärts, '++' bzw. '--' analog. Gibt es so etwas für AVR?
> ('Symbole erzeugen als Sprungmarken' ?)
Richtig tolle Assembler haben einen Symbolgenerator, der bei jedem
Aufruf einen neuen, noch nicht vorhandenen Namen (= Symbol) erzeugt. Das
kann man dann z.B. als Namen für Marken verwenden. Man braucht das vor
allem bei der Macroprogrammierung.
Man kann aber auch seine Programme in kleine sinnvolle Unterfunktionen aufteilen. Z.B. wie hier: Beitrag "Zeit + Temperatur auf LCD mit AVR" Dann kommt es meistens garnicht erst zu ellenlangem Spaghetticode, wo kreuz und quer gesprungen wird. Peter
> Verzweige vorwärts zum nächsten '+'; '-' entsprechend rückwärts, > '++' bzw. '--' analog. Gibt es so etwas für AVR? Der Gnu-Assembler (auch bei WinAVR mit dabei) unterstützt lokale Marken. Sie bestehen einfach aus einer Nummer. Bei Verwendung als Operand in einem Sprungbefehl wird ein 'b' (backward) oder ein 'f' (forward) an die Nummer angehängt. Der Assembler setzt für den Operand die Adresse der nächstengelegenen Marke der gewünschten Suchrichtung mit der entsprechenden Nummer ein. Lokale Marken lassen sich mehrfach verwenden und eignen sich ideal für kurze Sprünge, bei denen man sich nicht jedesmal neue Namen ausdenken möchte. Beispiel:
1 | 1: ; A |
2 | brcs 1f ; Sprung nach B |
3 | ... |
4 | 2: ; C |
5 | ... |
6 | rjmp 1b ; Sprung nach A |
7 | 1: ; B |
8 | rjmp 2b ; Sprung nach C |
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.