Forum: Mikrocontroller und Digitale Elektronik brne - Sprungweite nicht ausreichend


von Robert S. (razer) Benutzerseite


Lesenswert?

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

von .-.-. (Gast)


Lesenswert?

+- 64 Befehle ? sicher ?

von johnny.m (Gast)


Lesenswert?

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.

von johnny.m (Gast)


Lesenswert?

Ach ja: +-64 stimmt genaugenommen nicht ganz. Es sind +64/-63...

von Robert S. (razer) Benutzerseite


Lesenswert?

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?

von ReiRaWB (Gast)


Lesenswert?

@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

von Werner B. (Gast)


Lesenswert?

> Was macht das PC+2 beim brne genau?
Das ist die zusätzliche Sprungmarke

von MKII User (Gast)


Lesenswert?

statt PC+2 kannst Du auch folgendes schreiben. PC ist der 
Programmcounter
[avrasm]
cpi pattern, 0x04
brne PCplus2_label
rjmp pattern4
PCplus2_label:
...
 [\avrasm]

von Robert S. (razer) Benutzerseite


Lesenswert?

OK, danke. Was ist der Programm Counter genau?

Edit: Gerade Selbst gefunden. Die Adresse im ROM, die gerade 
abgearbeitet wird.

von Uhu U. (uhu)


Lesenswert?

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.

von senex24 (Gast)


Lesenswert?

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?

von Uhu U. (uhu)


Lesenswert?

> ('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.

von Peter D. (peda)


Lesenswert?

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

von yalu (Gast)


Lesenswert?

> 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

  

von senex24 (Gast)


Lesenswert?

Danke, yalu !

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
Noch kein Account? Hier anmelden.