Assembler RJMP x

LotadaC

Sehr aktives Mitglied
22. Jan. 2009
3.547
70
48
Marwitz
Sprachen
  1. BascomAVR
  2. Assembler
Was bewirkt

CodeBox Assembler
RJMP x
wenn für x irgendeine ganze Zahl eingesetzt wird?

Atmel Studio 6.1.27.30 (SP2)
 
Ich kann es grade nicht testen, ich hab's AVR Studio noch nicht wieder installiert. Aber soweit wie ich den Befehl verstanden habe (Opcode) navigiert der Befehlszeiger damit um x Bytes (oder Words) nach vorne bzw. hinten. Tendenziell oft mit Labels verwendet die der Compiler denn in die Positionen (Offsets) umsetzt.

Program execution continues at address PC + k + 1. The relative address k is from -2048 to 2047.

Ob der jetzt wirklich Bytegenau arbeitet oder in Words weiß ich nicht, ich vermute aber eher letzteres.
 
Hustekuchen...

Damit biste genauso reingefallen wie ich.
Wenn man im Instruction Set nachliest (Dein Zitat), sollte es eigentlich so sein (words). insbesondere sollte

CodeBox Assembler
RJMP -1
auf der Stelle hüpfen, 'ne leere Endlosschleife sein. Also dasselbe machen wie

CodeBox Assembler
loop:
 RJMP loop


Würde man so erwarten.

ABER die Zahl wird als absolute Zeilennummer (bzw Word-Adresse im Flash) interpretiert, nicht als Konstante "k" wie im Instruction Set angegeben, wobei unten bei null abgeschnitten wird...

In der Onlinehilfe hatte ich dann auch einen Hinweis darauf gefunden, daß RJMP im Assembler mit labeln arbeitet - trotzdem gehört mMn etwas Fantasie dazu, konkrete Zahlen als Label einer Zeilennummer zu verstehen...
 
Tatsache, da ist der Assembler wohl etwas missverständlich geschrieben.

> Eigentlich erwartet (R)JMP ja eine absolute Adresse, die dann vom
> Assembler entsprechend umgesetzt wird.
> RJMP PC+1 sollte daher richtiger sein als RJMP 1.
Im Prinzip richtig, aber auf PC kann man so nicht zugreifen. Der
Assembler interpretiert 1 als absolute Adresse. Da der rjmp an der
Stelle 0x0002 steht, muss dementsprechend um "-1" gehopst werden, um an
die Stelle "1" zu gelangen.

Also RJMP PC-1 statt RJMP -1
Denn soll der Assembler das als relativ interpretieren.

So leicht kann man sich täuschen 0.o
 
Nein...
Eigentlich erwartet RJMP absolute Entfernung und Richtung zur derzeitigen Position, also eine relative Adresse
InstructionSet zu RJMP schrieb:
Relative jump to an address within PC - 2K +1 and PC + 2K (words). For AVR microcontrollers with Program memory not
exceeding 4K words (8K bytes) this instruction can address the entire memory from every address location. See also JMP.

Operation: PC ← PC + k + 1
Syntax: RJMP k
Operands: -2K ≤ k < 2K
Program Counter: PC ← PC + k + 1
StackUnchanged
Der Opcode ist dann 1100 kkkk kkkk kkkk (also die Konsante als vorzeichenbehaftete (Zweierkomplement) 12bit Zahl)

Von der Adresse wo das RJMP steht, soll (k+1)-weit gesprungen werden. Also relativ.
So war das auch mal.

Der Assembler trägt jetzt aber eben nicht mehr k (als Zahl) ein, sondern macht auch aus'ner Zahl irgend'n Label. In der Onlinehilfe findet man dazu dann lediglich zusätzlich
In the assembler, labels are used instead of relative operands.
D.h. er interpretiert k jetzt als absolute Adresse (Word im Flash). Wobei alles kleiner als null dann als Null interpretiert wird. Dein (PC-x) wird berechnet, und dann als absolute Adresse verwertet (und ggf vorher bei null abgeschnitten). RJMP PC-0 springt auf der Stelle.

Laut InstructionSet müßte RJMP k für k=0b111111111111 dann 1100111111111111 als Opcode ergeben, also 0xFFCF (little endian).
Je nach Flash-Adresse in der das RJMP steht kommt aber was anderes raus, zB 0xFEC1 (Little endian, also 1100000111111110)
 
Zuletzt bearbeitet:
Hi,

Nein...
Eigentlich erwartet RJMP absolute Entfernung und Richtung zur derzeitigen Position, also eine relative Adresse

kenne ich auch so. Es sollte nach dem Opcode eine Zahl im Zweierkomplement stehen die dann die Differenz zum Zielbefehl angibt.
Der ProgramCounter (PC) steht allerdings normalerweise bei der Ausführung des RJMP schon auf dem nächsten Befehl im Flash.
So kenne ich das auf jeden Fall vom Z80. Bei einem RJMP 0 sollte also nichts passieren und einfach der nächste Befehl ablaufen.
Das wäre dann sozusagen ein komplizierter "NOP". ;) Die Differenz bezieht sich also auf die Adresse des auf den RJMP folgenden Befehl.

Gruß
Dino
 
Wie gesagt, eigentlich...
Das Atmel Studio (zumindest meine Version) interpretiert aber eben die Konstante k nicht (mehr, abweichend vom alten Instruction Set) als relative Sprungadresse, sondern als absolute Flash-Adresse, und berechnet dann quasi das Opcode-k daraus. Der Sinn dahinter erschließt sich mir nicht. (Da man so immer mit Labeln arbeiten muß, wenn irgendwo vor dem Sprungziel was geändert werden könnte. Solange das echt relativ wäre, würden lediglich Änderungen zwischen RJMP und Ziel problematisch sein, beim RJMP -1 also nicht...).

egal, kannst Du trotzdem mal checken, ob das auch in den alten Studio-Versionen schon so war, Dino?
Müßtest ja nur mal

CodeBox Assembler
NOP
RJMP -1
NOP

durch den jeweiligen Simulator jagen - wenn er auf das erste NOP jumpt, wars auch schon da so, wenn er auf der Stelle hüpft nicht...

(Ich hab hier derzeit keine alten Studio-Versionen)
Nachtrag:
...Die Differenz bezieht sich also auf die Adresse des auf den RJMP folgenden Befehl...
Richtig, deswegen ja auch
Operation: PC <-- PC + k + 1
 
Hi,

egal, kannst Du trotzdem mal checken, ob das auch in den alten Studio-Versionen schon so war, Dino?
Müßtest ja nur mal

CodeBox Assembler
NOP
RJMP -1
NOP

durch den jeweiligen Simulator jagen - wenn er auf das erste NOP jumpt, wars auch schon da so, wenn er auf der Stelle hüpft nicht...

öhhhmmm ... Den Simulator hab ich noch nie angepackt :eek:
Ich weiß nur das ich mal beim RJMP im Studio4 ne Meldung über ein Sprungziel außerhalb der Reichweite des Befehls bekommen hab. ;)

Gruß
Dino
 
kannst ja auch auf den Simulator verzichten, und Dir die erzeugten Opcodes ansehen. Die 3 Instruktionen sollten nach dem Instruction Set
Code:
00 00 FF CF 00 00 ...
ergeben - meine Version erzeugt da halt was anderes als FF CF...
(in Intel Hex rechne ich das jetzt aber nicht um - dafür ist entschieden zu wenig Coffein im Hirn...)
 
Um das ganze mal abzuschließen:
Die AVR arbeiten mit Prefetch - während eine Instruktion abgearbeitet wird, wird bereits die nächste in den Decoder geladen (bzw das nächste Word einer Doppelwort-Instruction). Folglich ist bereits der Program-Counter inkrementiert.

Deswegen würde ein "echter"

CodeBox Assembler
RJMP k
nach PC+k+1 springen.


CodeBox Assembler
RJMP -1
würde also auf der Stelle springen.
Der Assembler des ATMEL/AVR-Studios verarbeitet aber keine numerischen Konstanten, sondern absolute Label (und berechnet dann korrekt die relativen Konstanten).

Will man (zB bei Macros) auf Label verzichten, kann man den Program Counter selbst verwenden. Allerdings korrigiert der Assembler hier das Prefetch selbst.


CodeBox Assembler
RJMP PC
springt auf der Stelle, also PC+0 statt PC-1.

Neben RJMP betrifft das ganze natürlich ebenso RCALL und die ganzen Conditional Branches.

P.S.: selbst in der aktuellen L-Version des Instruction Sets von 11/2016 fehlt der Hinweis auf die Label, bzw steht der falsche Syntax mit "RJMP k"
 

Über uns

  • Makerconnect ist ein Forum, welches wir ausschließlich für einen Gedankenaustausch und als Diskussionsplattform für Interessierte bereitstellen, welche sich privat, durch das Studium oder beruflich mit Mikrocontroller- und Kleinstrechnersystemen beschäftigen wollen oder müssen ;-)
  • Dirk
  • Du bist noch kein Mitglied in unserer freundlichen Community? Werde Teil von uns und registriere dich in unserem Forum.
  •  Registriere dich

User Menu

 Kaffeezeit

  • Wir arbeiten hart daran sicherzustellen, dass unser Forum permanent online und schnell erreichbar ist, unsere Forensoftware auf dem aktuellsten Stand ist und der Server regelmäßig gewartet wird. Auch die Themen Datensicherheit und Datenschutz sind uns wichtig und hier sind wir auch ständig aktiv. Alles in allem, sorgen wir uns darum, dass alles Drumherum stimmt :-)

    Dir gefällt das Forum und unsere Arbeit und du möchtest uns unterstützen? Unterstütze uns durch deine Premium-Mitgliedschaft!
    Wir freuen uns auch über eine Spende für unsere Kaffeekasse :-)
    Vielen Dank! :ciao:


     Spende uns! (Paypal)