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