Ich bin leider anderweitig nicht fündig geworden, daher Frage ich hier:
Wie weit kann ich mit rjmp maximal springen?
Wie weit mit jmp?
Warum kann ich sowohl mit jmp als auch mit rjmp eine marke anspringen,
wo marken doch vom Assembler in (absolute) Adressen umgewandelt werden,
rjmp jedoch relative adressen verwendet?
Vielen Dank im Vorraus
Philipp
Das steht in der Befehlsreferenz:
"RJMP - Relative jump to an address within PC - 2K +1 and PC + 2K
(words)."
"JMP - Jump to an address within the entire 4M (words) Program memory"
>Warum kann ich sowohl mit jmp als auch mit rjmp eine marke anspringen,>wo marken doch vom Assembler in (absolute) Adressen umgewandelt werden,>rjmp jedoch relative adressen verwendet?
Ein bisschen Intelligenz ist da schon im Assembler ;-). Die Berechnung
der relativen Adresse basierend auf der momentanen Position und der
absoluten Adresse des Ziels ist ja nicht weiter schwierig.
Hallo Jan,
danke für Deine Antwort.
heißt das also Programm Counter + 2047 Bytes bzw. - 2046 bytes?
Cool, also weiß der Assembler das automatisch, ob ich relativ oder
absolut adressieren möchte?
Viele Grüße
Philipp
Philipp wrote:
> Cool, also weiß der Assembler das automatisch, ob ich relativ oder> absolut adressieren möchte?
Was heißt denn für dich "relativ" springen? Solange du deine
Codesegmente nicht zur Laufzeit durch den Flash hin- und herschiebst,
sind alle Adressen absolut. Ob das Codewort der der Stelle 100 jetzt
heißt "Springe drei Wörter nach vorne", um dann auf 103 zu landen, oder
ob direkt da steht "Springe nach 103"... das kommt aufs Gleiche raus.
>Cool, also weiß der Assembler das automatisch, ob ich relativ oder>absolut adressieren möchte?
Nein, das entscheidest du, indem du entweder jmp oder rjmp benutzt.
Verwendest du rjmp und ein Ziel, das mehr als 2K entfernt liegt gibt es
eine Fehlermeldung.
Eine Ausnahme sind die ATmega8xxx und ATtiny8xxx, die können mit
RJMP/RCALL die vollen 8kB erreichen.
Der Trick ist, sie springen bei >4kB Distanz über das Ende hinaus.
Peter
Die Sache mit dem Adressieren über das Ende des Flashs hinaus müssten
aber alle AVR können - insofern sind die 8kB-Varianten nichts
besonderes, es sind nur die größten, bei denen noch der gesamte Bereich
relativ angesprungen werden kann.
Genau gesagt, kann man alle Adressen erreichen, die zwischen
(PC-4094)mod(FlashSize) und (PC+4096)mod(FlashSize) liegen. Bei <=8kB
Flash sind das alle Adressen, bei 16kB genau die Hälfte und so weiter.
>>Ich bin leider anderweitig nicht fündig geworden...>>Wie weit kann ich mit rjmp maximal springen?
Was soll dieser absolut totale Quatsch bitte bedeuten?
Nicht fündig geworden...
Das steht
-DEUTLICH in der ersten ZEILE des Befehls im AVR Instruction-Set.
Das geht
-EINDEUTIG aus dem Datenblatt hervor.
Das steht
-KLAR UND FÜR JEDERMANN VERSTÄNDLICH in so ziemlich jedem Tutorial.
Wie bitte, kann man in Assembler programmieren, OHNE offenbar ein
einziges Exemplar des Instruction-Sets zu besitzen (in dem z.B. die
Antwort auf die Frage in der ersten Zeile des Befehls steht).
Und was genau bedeutet jetzt nochmal "nicht fündig geworden"?
Jochen Müller
@vistageek
Genau diese Frage hat sich mir auch aufgedrängt als ich diesen
wertvollen und kulturell bedeutsamen Beitrag von Herrn Jochen Müller
gelesen habe.
Jan M. wrote:
> Die Sache mit dem Adressieren über das Ende des Flashs hinaus müssten> aber alle AVR können
Könnte sein, aber der Assembler spielt da nicht mit.
Bei AVRs >8kB gibts ne Fehlermeldung, wenn man versucht, aus dem
Bootloader den Resetvektor anzuspringen.
Peter
>Nein, das entscheidest du, indem du entweder jmp oder rjmp benutzt.>Verwendest du rjmp und ein Ziel, das mehr als 2K entfernt liegt gibt es>eine Fehlermeldung.
Was mich dabei interessiert: Was läuft dabei im Assembler bzgl. den
Marken genau ab?
Erkennt der Assembler, wenn ich rjump verwende, dass er diese Marke
durch eine relative Adresse ersetzen muss, undbei jmp eine absolute?
>>Was soll dieser absolut totale Quatsch bitte bedeuten?>>Nicht fündig geworden...
Du hast zu viel Zeit.
Vielen Dank
Philipp
@Philip,
>>Was mich dabei interessiert: Was läuft dabei im Assembler bzgl. den>>Marken genau ab?>>Erkennt der Assembler, wenn ich rjump verwende, dass er diese Marke>>durch eine relative Adresse ersetzen muss, undbei jmp eine absolute?
Der Assembler durchläuft ja den Quelltext zeilenweise und berücksichtigt
dabei die ORG-Anweisungen etc. Er WEISS also bei jedem Befehl bei
welcher Codeadresse er gerade ist und legt eine Tabelle an, in der für
jedes Label (Marke) die zugehörige, echte Adresse steht. So kann er dann
einfach die relative Sprungdistanz für RJMP berechnen und natürlich die
absolute Sprungadresse für JMP.
Viele Assembler sind daher sogenannte "two-pass-assembler", d.h. sie
machen eigentlich 2 Durchläufe durch den Quelltext, den ersten um die
Symboltabelle anzulegen und den zweiten dann für die eigentlich
Übersetzung.
Allerdings geht es auch in nur einem Durchlauf, allerdings muss sich der
Assembler dann Zeilen merken, bei denen die Sprungadresse noch nicht
feststeht, wenn die Zeile gerade bearbeitet wird. Zum Beispiel weil es
ein Sprung an eine Marke weiter unten im Quelltext ist, deren Adresse
sich ja erst später ergibt. Nach dem Durchlauf werden dann die fehlenden
Adressen ersetzt, was bei vielen Marken dann aber einen zweiten
Durchlauf gleichkommt.
Ganz pedantisch betrachtet kann es eigentlich keinen wirklichen
"one-pass-assembler" geben, denn auf keinen Fall kann der Assembler ja
in die Zukunft blicken und bei Zeile 7 schon wissen welche physikalische
Adresse eine Marke haben wird, die erst bei Zeile 123 steht.
Immerhin muss er aber nicht den ganzen Quelltext zwei mal lesen.
Jochen Müller
Geht auch bei anderern devices, ist aber mit Vorsicht zu genießen, muß
dann in den Assembleroptionen aktiviert werden:
Zitat aus der Hilfe :
Wrap relative jumps
The AVR RJMP/RCALL instructions allow a 12-bit PC-relative offset,
corresponding to +/-2k words.
For devices with 4k words (8k bytes) or less FLASH program memory,
the Wrap option causes the assembler's offset calculation to wrap around
over the addressable program memory range, enabling the entire program
memory to be addressed using these instructions.
For devices with more than 4k words of program memory, using this option
may cause unpredictable results and it should be turned off.
If it is left on, the assembler will produce a warning when wrap takes
effect:
warning: Wrap rjmp/rcall illegal for device > 4k words - Turn off wrap
option and use jmp/call
This diagnostic is given as a warning and not an error to retain
compatibility with earlier versions of the assembler, but should be
treated as an error by the user. The JMP/CALL 2-word instructions take
22-bit absolute addresses and should be used instead.
Ist aber dann auch wirklich nur in einigen Ausnahmefällen interesant
falls man vom Anfnag zum Ende springen will.