AVR Instruction Set Opcode Frage

Hallo Gruppe,

ich habe mal eine Frage zu der Byteorder der Opcodes, die im AVR Instruction Set zu finden sind. Das PDF gibts übrigens unter

formatting link

Und zwar konnte ich da keine eindeutige Aussage darüber finden, welche Byteorder die eigentlich verwenden. Darum bin ich zunächst davon ausgegangen, dass das "as-is" ist. Stimmt aber leider nicht. In jedem

16-Bit-Block ist jeweils das High- mit den Lowbyte vertauscht. Zumindest generieren meine Assembler hier (avr-gcc bzw. tavrasm) solchen Code.

Bei 32-Bit Opcodes (jmp, call) wirds dann noch dubioser... so ist z.B. für "jmp" folgender Opcode gegeben

0: 1001 010x xxxx 110x 2: xxxx xxxx xxxx xxxx

Hierbei wären die "x" jetzt die Adresse. Die niedrigsten Bits wären jetzt in Byte 2, dann Byte 3, dann Byte 0 und dann Byte 1, sehe ich das richtig? Ich finde das nur sehr merkwürdig und würde gerne wissen, wo das genau dokumentiert ist.

Außerdem weiß ich auch nicht, ob vielleicht meine Architektur mir nen Streich spielt und auf nem Mac vielleicht was anderes rauskommen würde... naja ich will halt einfach auf Nummer sicher gehen.

Weiß jemand vielleicht mehr?

Vielen Dank, Gruß, Johannes

--
One can look at the designs of a bridge, realize it's built of tongue
depressers and bubble gum, and from this conclude that it is, indeed,
junk, without once having to take the actual suicidal risk of driving
across it. We do the same with your code.  Your code is crap.  [...]
                    - Kelsey Bjarnason in COLA about Jeff Relf's X.EXE
Reply to
Johannes Bauer
Loading thread data ...

Johannes Bauer schrieb:

Eine solche Aussage gibt es auch nicht, da der ROM 16-bit-weise organisiert ist. Du redest also nur über die Byteorder desjenigen, der die Opcodes von Deiner Datei in den ROM bekommt. Da die Byteorder in den Programmieranweisungen selbst ordentlich festgelegt ist, sollte das kein prinzipielles Problem sein.

Dann wäre noch der LPM-Befehl, da ist die Selektion des High- oder Low-Bytes ebenfalls explizit in der Beschreibung dokumentiert. Dieser verhält sich effektiv wie little-endian (Z.0 == 1 selektiert das high byte).

--
Jörg Wunsch

"Verwende Perl. Shell will man können, dann aber nicht verwenden."
				Kristian Köhntopp, de.comp.os.unix.misc
Reply to
Joerg Wunsch

Da muß ich dir leider widersprechen. Trotz 16-bit-Organisation

*adressiert* man das Flash byteweise. Die Aufklärung gibt das Datenblatt bei der Beschreibung des Adressierungsmodus "Constant Addressing Using the LPM Instruction" (beim 2313 auf Seite 12).

Zitat:

"Constant byte address is specified by the Z-register contents. The 15 MSBs select word address (0 - 1K), the LSB selects low byte if cleared (LSB = 0) or high byte if set (LSB = 1)"

Also ein niederer Indianer (low endian :-))

XL

Reply to
Axel Schwenke

Axel Schwenke schrieb:

Aber nur bei LPM. Der Befehlslesezyklus adressiert wortweise, die Offsets bei JUMP etc. sind entsprechend auch wortorganisiert. Alle Doku über die Programmierung erwähnt die high- und low-Bytes ebenfalls separat.

Daß LPM little-endian ist, schrob ich ja ebenfalls. ;-)

--
Jörg Wunsch

"Verwende Perl. Shell will man können, dann aber nicht verwenden."
				Kristian Köhntopp, de.comp.os.unix.misc
Reply to
Joerg Wunsch

Offensichtlich ist das Ansichtssache. Ich bevorzuge (wie der OP an- scheinend auch) die Sichtweise, daß das Flash ein linear adressiertes Array von Bytes ist und nur der Programmzähler ein implizites LSB hat, das immer Null ist. Demzufolge können Opcodes immer nur auf geraden Adressen stehen.

Interessant finde ich, wie avr-gcc (bzw. avr-gas) mit folgendem Codefragment umgeht (compilieren mit 'avr-gcc -Wa,-a -c test.S'):

----schnipp---- foo: nop .byte 1,2 bar: nop .byte 3 baz: nop

.org 10 rjmp foo rjmp bar ; rjmp baz

----schnipp----

Das ganze compiliert ohne Fehler, das nop bei 'baz' landet auf Adresse .text:0007. Wenn man aber die letzte Zeile ent-kommentiert, erhält man den erwarteten Fehler: 'Error:odd address operand: -7'

Stimmt. Hab ich wohl selektiv gelesen ;-)

Mir ging es im wesentlichen darum, daß die Frage des OP gar nicht so dumm ist. Einzig der Zugriff über den Programmzähler ist strikt wortorientiert. Sowohl Assemblerlistings als auch Hexfiles stellen das Flash byteweise dar. Auch beim Programmiervorgang beziehen sich die Adressen auf Bytes im Speicher.

XL

Reply to
Axel Schwenke

Axel Schwenke schrieb:

Mir dünkt aber, daß Atmel selbst überall von 16-bit-orientiert schreibt. Wobei sich das natürlich mit dem 8-bit-weise arbeitenden LPM beißt, keine Frage (was auch dazu führt, daß der ATmega128 halt RAMPZ und ELPM für diese Zugriffe braucht, obwohl er mit 16-bit Adressen in den Opcodes arbeitet).

Ja, die GNU tools sind sowieso byteorientiert. Schließlich sind die nicht nur schmalspurig auf 8- oder 16-bittig orientierte Targets ausgerichtet, sondern können alles bit 64-bit abhandeln.

Das ist doch aber eine Frage der Tools. Intel Hex Files können sich sowieso gar nichts anderes vorstellen. :-) Beim AVR-Assembler wäre ich mir gar nicht so sicher, ob er nicht 16-bit-weise in den Listings arbeitet. Andere Tools wie VMLAB (und vermutlich auch AVR Studio, das ich nicht benutzen kann, da es nicht in Wine läuft) arbeiten hier

16-bit-orientiert.

Nö.

Load 0100 H000 xxxx xxxx xbbb bbbb iiii iiii Write H (high Program or low) data Memory i to Program Page Memory page at word address b. Data low byte must be loaded before data high byte is applied within the same address.

Man beachte die ausdrückliche Nennung einer Wortadresse. Auch die vorgeschriebene Prozedur (erst low-byte, dann high-byte) deutet darauf hin, daß der ROM wirklich wortweise geschrieben wird, d. h. das low- byte wird beim ersten Aufruf zwischengespeichert, erst mit dem high- byte kann die ganze Zelle dann beschrieben werden.

Ist natürlich eine ziemlich akademische Diskussion. ;-)

--
Jörg Wunsch

"Verwende Perl. Shell will man können, dann aber nicht verwenden."
				Kristian Köhntopp, de.comp.os.unix.misc
Reply to
Joerg Wunsch

He, he, danke aber auch! ;-)

Ah ja, das macht die Sache echt klarer. Und die Worte sind dann little endian. Sehr schön, dann komm ich da etwas voran :-)

War nur etwas verwirrt, weil ja z.B. der 1200 oder 2313 ja 8-bit uCs sind, dass die Opcodes jeweils in 16-bit-Häppchen kommen hat mich etwas irritiert. Aber eigentlich logisch, bei den Adressen, die man aus den rjmp/rcall-Opcodes rauslesen kann muss man ja auch immer mit 2 multiplizieren, damit man das "echte" (byteweise) Offset herausbekommt.

Viele Grüße Johannes

--
One can look at the designs of a bridge, realize it's built of tongue
depressers and bubble gum, and from this conclude that it is, indeed,
junk, without once having to take the actual suicidal risk of driving
across it. We do the same with your code.  Your code is crap.  [...]
                    - Kelsey Bjarnason in COLA about Jeff Relf's X.EXE
Reply to
Johannes Bauer

Wiegesagt, das macht die Sache klarer. Ich dachte auch der ROM hätte

8-bit Organisation. Danke für die Antwort!

Gruß, Johannes

--
One can look at the designs of a bridge, realize it's built of tongue
depressers and bubble gum, and from this conclude that it is, indeed,
junk, without once having to take the actual suicidal risk of driving
across it. We do the same with your code.  Your code is crap.  [...]
                    - Kelsey Bjarnason in COLA about Jeff Relf's X.EXE
Reply to
Johannes Bauer

Örks. Die Manuals von AVR sind auch nicht optimal [1]. Zum 2313 und 8535 sagt das Manual übereinstimmend:

"The program and data memory arrays ... are programmed byte-by-byte in either programming mode."

Bei der Beschreibung der Programmiersequenz steht dann zwar nur "Load Adress Low/High Byte", aber aus der Anzahl Bits und der Flash-Größe kann man dann schließen, daß eine Wort-Adresse gemeint sein muß.

Oh und ich sehe gerade, daß das die Beschreibung des parallelen Programmiermodus ist. Beim seriellen stehts dann wie oben...

Wohl wahr.

[1] Es wäre IMHO angebracht, die Teile als *Familie* darzustellen. Also erstmal alles beschreiben, was bei allen gleich ist. Dann eine Tabelle, was wem fehlt.

XL

Reply to
Axel Schwenke

Die Byteorder haengt von der Speicherarchitektur ab. Die CPU arbeitet mit 16-Bit Opcodes.

Hier ein Ausschnitt aus meinem Disassembler, der allerdings, wie Du aus der Zuordnung der Bits des ersten Wortes erkennen kannst, die Daten "falschrum" aus dem Speicher liest (und zudem die Sprung-Adresse auf Bytes gerechnet ausgibt, damit es mit einem Hexdump uebereinstimmt). Diese Methodik deckt sich gut mit der IAR Toolchain, aber nicht so sehr mit Atmels eigenem Assembler (den man eh nicht verwenden sollte).

if ((op & 0xfe0e) == 0x940c) { // JMP AddMnemonic("jmp"); Add_CallDest(); AdvancePipe(); }

void Add_CallDest(void) { // CALL, JMP ulong d; d = (ulong)( (op&0x0001) | ((op&0x01f0)>>3) )

Reply to
jetmarc

,

Bei maximal 1 Befehl pro Takt hat man bei 16MHz f=FCr das Laden eines Befehles 62ns Zeit. Ich halte dabei ein 16Bit-Flash mit 60ns f=FCr deutlich realistischer als ein 8Bit-Flash mit 30ns.

Markus

Reply to
Markus Kaufmann

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.