Forum: Mikrocontroller und Digitale Elektronik AVRASM: Sprünge mit PC +/- X


von Philipp B. (philipp_burch)


Lesenswert?

Hallo zusammen,

im Allgemeinen ist es im AVR Assembler ja üblich, ein Label zu
definieren und per rjmp, breq, ... dorthin zu springen. Allerdings gibt
es ja auch die Möglichkeit über den Programmcounter (PC) um einfach
einige Anweisungen nach "vorne"/"hinten" zu springen.
Beispiel:
1
  lds temp2, RAMSTART + A_MENULEVEL
2
  tst temp2
3
  brne PC + 6
4
    lds temp1, RAMSTART + A_MENUENTRY0
5
    lds temp2, RAMSTART + A_MENUMAXE0
6
  rjmp PC + 4
7
    lds temp1, RAMSTART + A_MENUENTRY1
8
    lds temp2, RAMSTART + A_MENUMAXE1

Das funktioniert so, aber mir ist nicht ganz klar, wie man den
korrekten Betrag für den Programmcounter ausrechnet. Um eine einzelne
Zeile zu überspringen scheint ja 2 der richtige Betrag zu sein. Beim
oben genannten brne ist es 6 für drei Zeilen, daher eigentlich immer zu
überspringende Zeilenzahl * 2. Aber stimmt das wirklich so?
An einem anderen Ort im Programm hab' ich z.B. diese Konstruktion:
1
  sbic PIND, 3
2
  rjmp PC + 4
3
    sbrs Buttons, BTN_ENTER
4
      sbr Buttons, 1 << BTN_ENTER_F
5
    rjmp PC + 2
6
    cbr Buttons, 1 << BTN_ENTER
Auch das funzt, obwohl hier beim ersten rjmp mit dem Betrag 4 gleich
drei Anweisungen übersprungen werden :-/
Spielt die Art der Anweisungen eine Rolle?

Ich wäre froh, wenn mir das mal jemand erklären könnte, im Datenblatt
finde ich grade nix dazu...

Danke im Voraus!

von A.K. (Gast)


Lesenswert?

Wär' ich vorsichtig mit sowas. Atmels Assembler rechnet in Worten, GNUs
Assembler in Bytes. Kann man leicht verwirrt werden.

von Michael Nagler (Gast)


Lesenswert?

Der AVR Assembler übersetzt den Quelltext in 16 Bit breite
Maschinenbefehle (Opcode). In der Assemblerhilfe ist der Opcode zu
jedem Assemblerbefehl dargestellt. Man muss also wissen, wieviele Words
Maschinencode übersprungen werden müssen, um das korrekte Sprungziel
errechnen zu können.
Beim Disassemblieren werden die Opcodes ausgewertet und in lesbaren
Text umgesetzt. Da der Name der Sprungmarke beim assemblieren verloren
geht, kann der Disassembler nur relative Sprungmarken zurückgewinnen
(PC +/- x Words), wenn keine extra Debug-Info gespeichert wird.
Selbst einen solchen Quelltext ohne Sprungmarken zu schreiben würde ich
allerdings dringend vermeiden, weil m. E. die Fehlersuche enorm
erschwert wird.

Gruß
Michael

von Jadeclaw D. (jadeclaw)


Lesenswert?

Ja, die Art der Anweisungen ist hier entscheidend.
Schau mal hier rein:
http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf
Dieses File enthält den kompletten Befehlssatz,
inklusive Angaben darüber, wieviele Words und Takte ein Befehl
verbraucht.

Übrigens, diese Art der Sprungzielberechnung ist nicht zu empfehlen,
man ändert irgendwo etwas, vergisst u. U. dann den Offset anzupassen,
mit dem Ergebnis, dass man sich 'nen Wolf sucht.
Mit festen Labels kann der Assembler das auch selber tun.

Gruss
Jadeclaw.

von Philipp B. (philipp_burch)


Lesenswert?

Ok, das wollte ich wissen, danke euch.
Ich verwende meistens ja auch Labels als Sprungziele, aber wenn es nur
so ein, zwei, höchstens vier Zeilen sind, finde ich diese Möglichkeit
noch praktisch. Jedenfalls sucht man so auch nicht länger nach einem
Fehler, als wenn man zwei ähnlich geschriebene Labels hat und irgendwo
aus Versehen zum falschen springt... Aber für was hat man ja den
Debugger ;)

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.