Forum: Mikrocontroller und Digitale Elektronik AVR: Werden gleiche Opcodes unterschieden?


von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Hallo Leute,

ich hab da nochmal eine Frage zu den AVR Opcodes.

Es scheinen ein paar Opcodes mehrfach belegt zu sein, z.B. haben die 
ASM-Befehle BRBC und BRCC den selben Opcode.

An anderer Stellen habe ich das Gefühl, dass sich Opcodes aufgrund der 
Argumente überschneiden können, so z.B. die Befehle BRBS, BRCS und BRLO.

Für BRBS gilt der Opcode:
1111 00kk kkkk ksss <- 0 <= s <= 7; -64 <= k <= +63

Für BRCS gilt der Opcode:
1111 00kk kkkk k000 <- -64 <= k <= +63

Sind jetzt die Argumente für BRBS beide 0 und für BRCS auch 0 so erhält 
man die gleichen Opcodes.

So jetzt die Fragen:
Wie unterscheidet die CPU diese Befehle? Ist eine Unterscheidung 
überhaupt notwendig?


Und wie sieht es aus, wenn man das ganze umdreht:
Man hat ein Hex-File das man interpretieren möchte (z.B. ein Emulator).
Wenn ich in dem Hex-File auf einen entsprechenden Opcode treffe, kann 
ich mir dann einfach aussuchen ob ich nun BRBS, BRCS oder BRLO nehme?

Wäre schön, wenn Ihr mir helfen könntet :)

Grüße

von Lurchi (Gast)


Lesenswert?

Die Unterscheidung ist nicht nötig. Die mehrfach vorkommenden Opcodes 
sind spezielle Fälle, die es dem Nutzer einfacher machen sollten. Der 
BRBS Befehl ist die allgemeine Form, dazu gibt es dann je nach Flag noch 
spezielle Namen.


Neben den Sprüngen gibt es da noch ein paar andere Spezialfälle die 
andere Namen bekommen. Etwa AND mit sich selbst heißt auch TST oder EOR 
mit sich selbst als CLR.

von S. Landolt (Gast)


Lesenswert?

Sie haben soeben das Geheimnis von Atmels "131 Powerful Instructions" 
gelüftet: da hat's einige Dubletten drin. Zum Beispiel auch sbr und ori, 
oder cbr und andi.

von g457 (Gast)


Lesenswert?

> Es scheinen ein paar Opcodes mehrfach belegt zu sein, z.B. haben die
> ASM-Befehle BRBC und BRCC den selben Opcode.

Jein. BRCC ist halt einfach BRBC(carry). Weil man BRBC(carry) häufig 
braucht kann man dafür auch ein neues Mnemonic einführen. Das nennt man 
dann BRCC und definiert das zu prüfende Bit als carry.

von Andreas B. (andreas_b77)


Lesenswert?

> Für BRBS gilt der Opcode:
> 1111 00kk kkkk ksss <- 0 <= s <= 7; -64 <= k <= +63
>
> Für BRCS gilt der Opcode:
> 1111 00kk kkkk k000 <- -64 <= k <= +63

Das ist keine Doppelbelegung, BRCS ist schlicht ein Spezialfall von 
BRBS, nämlich BRBS auf Bit 0 (= Carry). Das ist nur um den Assembler 
Code besser lesbar zu machen. Aus dem Maschinencode kannst du dann 
natürlich nicht mehr schließen, was in den Assemblerquellen stand.

von (prx) A. K. (prx)


Lesenswert?

BRBS – Branch if Bit in SREG is Set
BRCS – Branch if Carry Set
Carry ist Bit 0 im SREG

BRLO bezieht sich auf das Ergebnis eines Vergleichs ohne Vorzeichen. Bei 
"lower" ist danach Carry gesetzt.

: Bearbeitet durch User
von Carl D. (jcw2)


Lesenswert?

BRBS Label,0    branch on status bit set
und
  BRCS Label      branch on carry set
Sind deswegen identisch, weil Carry im Bit0 des SREG liegt.
Solche "Abkürzungen" gibt's für alle Status Bits.

Zu lang getippt ;-)

: Bearbeitet durch User
von c-hater (Gast)


Lesenswert?

Kaj G. schrieb:

> Es scheinen ein paar Opcodes mehrfach belegt zu sein, z.B. haben die
> ASM-Befehle BRBC und BRCC den selben Opcode.

Du siehst das unter dem falschen Betrachtungwinkel. Es ist nämlich 
einfach nur so, dass Atmel etliche fiktive Instruktionen geschaffen hat, 
die es nur auf Asm-Quelltextebene gibt. Der Sinn der Sache war reines 
Marketing. Man konnte halt dann in's DB schreiben dass z.B. 112 
Instruktionen unterstützt werden, obwohl es de facto nur 70 oder so 
sind.

Tatsächlich schnurrt das deutlich zusammen, wenn man es auf die echten 
Opcodes reduziert. Bei vielen dieser Instruktionen merkt man es 
garnicht, das sind echte (also wirklich vollständig nutzlose) 
Alias-Instruktionen. Z.B. "ori" vs. "sbr". Oder auch "ldi 
reg,-1/255/$ff" vs. "ser".
Einige andere sind nur wenig intelligenter, z.B. "andi" vs. "cbr". 
Tatsächlich macht der Assembler still und heimlich einfach aus dem "cbr 
reg,immediate" ein "andi reg,~immediate". Was von der Wirkung her 
absolut dasselbe ist.
Bei den Branch-Instruktionen ging es aber nicht so einfach zu 
vertuschen, dass viele der angeblichen Instruktionen eigentlich garnicht 
wirklich existieren, das Dokumentation der Branches im "instruction set 
reference manual" versucht aber immerhin noch, die Sache möglichst 
undurchsichtig zu gestalten, so dass man eine Weile braucht, eh' man 
dahinterkommt, was hier wirklich Phase ist...

> So jetzt die Fragen:
> Wie unterscheidet die CPU diese Befehle?

Garnicht. Sie bekommt sie ja nie zu sehen, weil sie nicht wirklich 
existieren, sondern nur im Auftrag der Marketingfritzen vorgegaukelte 
Potjomkinsche Dörfer sind.

> Und wie sieht es aus, wenn man das ganze umdreht:
> Man hat ein Hex-File das man interpretieren möchte (z.B. ein Emulator).

Natürlich düster. Wo es de facto keinen Unterschied gibt, gibt es 
natürlich auch keine Information im Binärcode. D.h.: du musst die Sache 
auf den Umfang des tatsächlich verfügbaren reduzieren und dich für eine 
der möglichen (funktional sowieso absolut gleichwertigen) 
Quelltextrepresentationen entscheiden.

von Kaj G. (Firma: RUB) (bloody)


Lesenswert?

Ich danke euch :)
Das macht es dann doch etwas einfacher.

Grüße

von Axel S. (a-za-z0-9)


Lesenswert?

c-hater schrieb:
>> Es scheinen ein paar Opcodes mehrfach belegt zu sein, z.B. haben die
>> ASM-Befehle BRBC und BRCC den selben Opcode.
>
> Du siehst das unter dem falschen Betrachtungwinkel. Es ist nämlich
> einfach nur so, dass Atmel etliche fiktive Instruktionen geschaffen hat,
> die es nur auf Asm-Quelltextebene gibt. Der Sinn der Sache war reines
> Marketing. Man konnte halt dann in's DB schreiben dass z.B. 112
> Instruktionen unterstützt werden, obwohl es de facto nur 70 oder so
> sind.

Das ist Blödsinn.

Gerade bei den Instruktionen, die der TE zeigt, ist es einfach so, daß 
die gleiche Konstellation der Flags je nach Kontext verschiedene 
Bedeutung haben kann. Mnemonics sollen aber gerade einprägsam sein. Dann 
ist es durchaus logisch und zielführend, zwei verschiedene Mnemonics für 
die gleiche Operation einzuführen. Und das gab es schon vor den AVR.

Beispiel 6502: da gibt es einen bedingten Sprung, der bei gesetztem 
Carry-Flag genommen wird. Den kann man jetzt wahlweise als
1
BCS label
oder
1
BGE label

schreiben. Das erste Mal ist es Branch if Carry Set (springe, wenn 
Carry gesetzt) und man würde es typisch nach einer arithmetischen oder 
logischen Operation ausführen, wenn man den Überlauf ins Carry-Flag 
behandeln will. Die zweite Variante meint Branch when Greater or Equal 
(springe, wenn größer oder gleich) und man würde es typischerweise nach 
einer arithmetischen Vergleichsoperation ausführen. Der Prozessor würde 
in jedem Fall das gleiche machen: kucken ob das C-Flag gesetzt ist, und 
wenn ja, den Sprung ausführen. Und deswegen wird das natürlich auch 
durch den gleichen Opcode codiert.

Ein anderer Kandidat wäre die Operation, ein Register zu löschen. Wenn 
es bereits einen Opcode gibt, der zwei Register XOR-verknüpft:
1
XOR r1, r2
dann wäre es durchaus sinnvoll, dem Programmierer einen Mnemonic
1
CLR r1
zur Verfügung zu stellen, der intern als
1
XOR r1, r1
codiert ist.

Auch hier ist das Ziel nicht das Marketing "meiner hat mehr Opcodes als 
deiner!!1elf!" sondern die bessere Lesbarkeit des Programmcodes.

von (prx) A. K. (prx)


Lesenswert?

Das war jetzt aber etwas fies - mit dem 6502 ausgerechnet einen 
Prozessor einzuflechten, der bei Subtraktion/Compare das Carry andersrum 
setzt als AVR. ;-)

von LostInMusic (Gast)


Lesenswert?

>Bei den Branch-Instruktionen ging es aber nicht so einfach zu vertuschen,

Deine Antipathie gegen die redundanten Mnemonics finde ich übertrieben. 
Hersteller von CPUs erfinden solche weder zum Spaß noch in unlauterer 
Absicht, sondern schlicht, um Assembler-Quelltexte leichter lesbar zu 
machen (für Menschen).

>also wirklich vollständig nutzlose

Nein, denn ich benutze die Mnemonics CLR, TST und BREQ etc. - oft und 
gerne. Damit sind sie für mich (wie für viele andere sicher auch) nicht 
nutzlos.

Schreibst Du wirklich immer "EOR r16, r16" statt "CLR r16" und "AND r16, 
r16" statt "TST r16"?

Den Erklärungen von A. Schwenke schließe ich mich an.

von Lothar (Gast)


Lesenswert?

Axel S. schrieb:
> Beispiel 6502: da gibt es einen bedingten Sprung, der bei gesetztem
> Carry-Flag genommen wird. Den kann man jetzt wahlweise als
> BCS label : Branch if Carry Set
> oder
> BGE label : Branch if Greater or Equal

Hier sieht man dass der ARM der 6502 Nachfolger ist, da ist es genauso 
:-)

BCS : Branch if Carry set
oder
BHS : Branch if Higher or same

von Axel S. (a-za-z0-9)


Lesenswert?

A. K. schrieb:
> Das war jetzt aber etwas fies - mit dem 6502 ausgerechnet einen
> Prozessor einzuflechten, der bei Subtraktion/Compare das Carry andersrum
> setzt als AVR. ;-)

Heh, das war mir noch gar nicht aufgefallen :)

Das macht meine Erklärung ja noch einsichtiger. Denn wenn ich BGE oder 
BLT (Branch when Less Than) benutze, dann muß ich mich ja genau nicht 
damit herumschlagen wie herum CMP die Subtraktion [1] macht und ob ich 
jetzt auf gesetztes oder gelöschtes Carry-Flag testen muß.


[1] die meisten Architekturen implementieren den Vergleich (CMP) als 
Subtraktion, bei der das Ergebnis einfach nirgendwohin gespeichert wird.
So gesehen ist der CMP Mnemonic auch redundant.

von Thomas E. (picalic)


Lesenswert?

Axel S. schrieb:
> So gesehen ist der CMP Mnemonic auch redundant.

Nein, redundant wäre er nur, wenn es beim SUB-Befehl die Option gäbe, 
das Ergebnis nicht zu speichern.

von Falk B. (falk)


Lesenswert?

@ Axel Schwenke (a-za-z0-9)


>Das macht meine Erklärung ja noch einsichtiger. Denn wenn ich BGE oder
>BLT (Branch when Less Than) benutze, dann muß ich mich ja genau nicht
>damit herumschlagen wie herum CMP die Subtraktion [1] macht und ob ich
>jetzt auf gesetztes oder gelöschtes Carry-Flag testen muß.

Daran erkennt man, daß sogar Assembler eine überaus abstrakte 
Hochsprache ist ;-)

>[1] die meisten Architekturen implementieren den Vergleich (CMP) als
>Subtraktion, bei der das Ergebnis einfach nirgendwohin gespeichert wird.
>So gesehen ist der CMP Mnemonic auch redundant.

Ja, aber mit diesen Details will sich nicht mal der ASM-Programmierer 
herumschlagen, das kann der Assembler (die Software) deutlich besser.
Außer vielleicht Leuten, die PIC-Assembler programmieren 8-0

von Thomas E. (picalic)


Lesenswert?

Zur Carry-Logik: Wenn man such vor Augen hält, daß eine Subtraktion 
eigentlich auch nur die Addition des negierten (= 2er-Komplement) Wertes 
ist, finde ich den AVR hier etwas "unlogischer".

Bit-Manipulation: Kommt man von Architekturen mit tatsächlich 
vorhandenen Bit-Set und -Reset Befehlen, fällt man in der Regel erstmal 
drauf rein, daß beim AVR das Status-Register beeinflusst wird.

: Bearbeitet durch User
von Andreas B. (bitverdreher)


Lesenswert?

Axel S. schrieb:
> Beispiel 6502: da gibt es einen bedingten Sprung, der bei gesetztem
> Carry-Flag genommen wird. Den kann man jetzt wahlweise als
> BCS label
> oderBGE label

Hmm, BGE habe ich nie kennengelernt. Welchen Assembler hattest Du denn 
verwendet. Ich kenne vom 6502 nur:
BCC/BCS, BEQ/BNE, BPL/BMI, BVC/BVS.
Diese Sprungbefehler bezogen sich alle direkt auf die Flags.

Als Assemberproigrammierer da redundante Befehle reinzumogeln finde ich 
nicht sehr sinnvoll. Wenn ich Assembler programmiere, weiß ich was ich 
tue.

Aber ok, meist hatte ich den 6502 in Maschinensprache programmiert. 
(Handübersetzt anhand der Op code Liste ;-) )

Gruß
Andreas

von guest (Gast)


Lesenswert?

LostInMusic schrieb:
> Schreibst Du wirklich immer "EOR r16, r16" statt "CLR r16" und "AND r16,
> r16" statt "TST r16"?

<flamewar>
Ich persönlich beschäftige mich lieber mit der Aufgabe und überlasse dem 
Compiler solche Spitzfindigkeiten ;-)
</flamewar>

von Rolf M. (rmagnus)


Lesenswert?

Lurchi schrieb:
> Neben den Sprüngen gibt es da noch ein paar andere Spezialfälle die
> andere Namen bekommen. Etwa AND mit sich selbst heißt auch TST oder EOR
> mit sich selbst als CLR.

Selbst der left-Shift ist nur eine Addition eines Registers mit sich 
selbst.

von Falk B. (falk)


Lesenswert?

@  Rolf Magnus (rmagnus)

>> Neben den Sprüngen gibt es da noch ein paar andere Spezialfälle die
>> andere Namen bekommen. Etwa AND mit sich selbst heißt auch TST oder EOR
>> mit sich selbst als CLR.

>Selbst der left-Shift ist nur eine Addition eines Registers mit sich
>selbst.

Wenn es nur um ein Bit ist, ja. Diesen Trick nutzt sogar der avr gcc 
manchmal. Trotzdem sind es beim AVR verschiedene Op-Codes und im 
Silizium verschiedene Operationen.

von LostInMusic (Gast)


Lesenswert?

>Trotzdem sind es beim AVR verschiedene Op-Codes und im Silizium verschiedene 
Operationen.

Abgesehen davon, dass das H-Flag selten genutzt wird, gibt es 
diesbezüglich einen weiteren Unterschied: Bei ADD wird es gegebenenfalls 
gesetzt, bei LSL nie.

von Rolf M. (rmagnus)


Lesenswert?

Falk B. schrieb:
> @  Rolf Magnus (rmagnus)
>
>>> Neben den Sprüngen gibt es da noch ein paar andere Spezialfälle die
>>> andere Namen bekommen. Etwa AND mit sich selbst heißt auch TST oder EOR
>>> mit sich selbst als CLR.
>
>>Selbst der left-Shift ist nur eine Addition eines Registers mit sich
>>selbst.
>
> Wenn es nur um ein Bit ist, ja.

Der AVR hat nur ein-Bit-Shifts.

> Diesen Trick nutzt sogar der avr gcc manchmal. Trotzdem sind es beim AVR
> verschiedene Op-Codes und im Silizium verschiedene Operationen.

Nein, sind sie nicht. LSL rX und ADD rX,rX sind die selbe Operation.

LostInMusic schrieb:
> Abgesehen davon, dass das H-Flag selten genutzt wird, gibt es
> diesbezüglich einen weiteren Unterschied: Bei ADD wird es gegebenenfalls
> gesetzt, bei LSL nie.

Auch das stimmt nicht.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

Andreas B. schrieb:
> Axel S. schrieb:
>> Beispiel 6502: da gibt es einen bedingten Sprung, der bei gesetztem
>> Carry-Flag genommen wird. Den kann man jetzt wahlweise als
>> BCS label oder BGE label
>
> Hmm, BGE habe ich nie kennengelernt. Welchen Assembler hattest Du denn
> verwendet.

Ist lange her. Vermutlich Professional Ass, mit dem habe ich damals das 
meiste gemacht: http://csdb.dk/release/?id=139650

> Ich kenne vom 6502 nur:
> BCC/BCS, BEQ/BNE, BPL/BMI, BVC/BVS.
> Diese Sprungbefehler bezogen sich alle direkt auf die Flags.

Schon klar.

Ich hatte ursprünglich eigentlich etwas anderes im Gedächtnis und jetzt 
ist es mir wieder eingefallen: Z8 Assembler. Da gibt es für bedingte 
Sprünge auch redundante Mnemonics. Z.B. JRZ == JREQ und JRNZ == JRNE. 
Mit (N)Z für (Non)Zero und EQ/NE für EQual/Not Equal. Das JR steht für 
Jump Relative. Für die Carry-bedingten Sprünge gab es auch jeweils zwei 
Varianten.

von LostInMusic (Gast)


Lesenswert?

>Auch das stimmt nicht.

OK, Punkt für Dich - der Simulator im AVRStudio hat die Frage zu Deinen 
Gunsten entschieden. Zur Entschuldigung meines Irrtums verweise ich auf 
die Instruction Set Summaries in den Datenblättern zum ATmega8/16/32 + 
88/168/328 + 13 + 25/45/85 (mehr habe ich mir nicht angesehen). Darin 
ist nämlich die LSL-Instruktion offensichtlich falsch beschrieben (*). 
Wer ahnt denn sowas? :-( Die Angaben im Atmel Instruction Set und in der 
Doku zum AVRAssembler sind dagegen korrekt.

(*)
Der Eintrag für LSL in den Instruction Set Summaries lautet (Operation 
und beeinflusste Flags):
Rd(n+1) ← Rd(n), Rd(0) ← 0
Z,C,N,V

Richtig wäre:
Rd ← Rd + Rd
Z,C,N,V,H

von Falk B. (falk)


Lesenswert?

@ Rolf Magnus (rmagnus)

>> Diesen Trick nutzt sogar der avr gcc manchmal. Trotzdem sind es beim AVR
>> verschiedene Op-Codes und im Silizium verschiedene Operationen.

>Nein, sind sie nicht. LSL rX und ADD rX,rX sind die selbe Operation.

Tatsache! Hätte ich nicht gedacht.

>> Abgesehen davon, dass das H-Flag selten genutzt wird, gibt es
>> diesbezüglich einen weiteren Unterschied: Bei ADD wird es gegebenenfalls
>> gesetzt, bei LSL nie.

>Auch das stimmt nicht.

Naja, also ist auch die elementar erscheinende Funktion lsl ein 
Pseudo-ASM Befehl!!!!

von P. M. (mikro23)


Lesenswert?

Falk B. schrieb:
>>Nein, sind sie nicht. LSL rX und ADD rX,rX sind die selbe Operation.
>
> Tatsache! Hätte ich nicht gedacht.

Um noch das Letzte zu ergänzen:

ROL Rn = ADC Rn,Rn

von c-hater (Gast)


Lesenswert?

Axel S. schrieb:

> Gerade bei den Instruktionen, die der TE zeigt, ist es einfach so, daß
> die gleiche Konstellation der Flags je nach Kontext verschiedene
> Bedeutung haben kann. Mnemonics sollen aber gerade einprägsam sein.

Und einprägen kann man sich was wohl besser: kleine Listen von Memnonics 
oder große Listen?

Das was du meinst, ist was ganz anderes. Und es hilft nur Leuten, die 
mit der binären Mathematik auf Kriegsfuss stehen und deswegen nicht die 
Semantik erfassen, die die Operation an gerade der Stelle des Codes hat, 
an der sie steht.

Und selbst denen hilft es nicht wirklich, denn den ganzen Zauber der 
Pseudoinstruktionen könnte man genausogut mit Makros abhandeln, das muss 
nicht in den Assembler selber rein, da hätte der Hersteller auch einfach 
einen Set entsprechender Makros mitliefern können, wenn seine primäre 
Intention tatsächlich nur gewesen wäre, unbedingt den Usern helfen zu 
wollen.

Dann hätten die, die es brauchen oder für nützlich halten, einfach diese 
Makros benutzen können. Und alle anderen hätten es eben einfach nicht 
getan. Oder ihre eigenen Makrosets verwendet...

Aber dann hatten sie eben die Zahl der tatsächlich unterstützten 
Instruktionen in's DB schreiben müssen, was marketingtechnisch halt 
nicht so gut gekommen wäre...

> Beispiel 6502: da gibt es einen bedingten Sprung, der bei gesetztem
> Carry-Flag genommen wird. Den kann man jetzt wahlweise als
>
>
1
> BCS label
2
>
> oder
>
1
> BGE label
2
>
>
> schreiben.

Unsinn. Zufällig hatte ich mal einen Atari800XL, den ich natürlich auch 
in Assembler programmiert habe. Und das Gute war bei dem Ding gerade, 
dass eine 1:1-Beziehung zwischen Mnemnonic und OpCode bestand. Ähem, 
eigentlich was das aber auch schon fast das einzig Gute an der 
Architektur. Trotzdem habe ich das Ding damals mit Begeisterung 
beackert. Naja, gerade beim 8Bit-Atari war ja auch nicht die CPU der 
Kracher, sondern die Fähigkeiten der Custom-Chips.

So ähnlich wie später beim Amiga. Wobei ich den 68k doch schon sehr nett 
fand, kein Vergleich mit der 6502-Gurke des Atari. War bloss ein wenig 
niedrig getaktet und in den tatsächlich verbreiteten Systemen auch noch 
zusätzlich durch den langsamen RAM ausgebremst, bei dem er sich die 
Bandbreite mit den Custom-Chips teilen musste. Gab's eigentlich beim 
68k-Assembler solche redundanten Pseudo-Instruktionen? Kann mich nicht 
mehr 100%ig erinnern, aber ich bin fast sicher: nein, diesen Schwachsinn 
gab es dort auch nicht.

von (prx) A. K. (prx)


Lesenswert?

Thomas E. schrieb:
> Zur Carry-Logik: Wenn man such vor Augen hält, daß eine Subtraktion
> eigentlich auch nur die Addition des negierten (= 2er-Komplement) Wertes
> ist, finde ich den AVR hier etwas "unlogischer".

Sieh es so: AVR addiert das Zweierkomplement, 6502 das Einerkomplement.

von S. R. (svenska)


Lesenswert?

c-hater schrieb:
> Und einprägen kann man sich was wohl besser: kleine Listen von Memnonics
> oder große Listen?

Weder noch: Logische Listen von Mnemonics.

Mich interessiert es nicht, wie ADD, SUB oder CMP mit Carry/Overflow 
umgehen, daher möchte ich einen Satz Branch-Mnemonics für Arithmetik 
(größer/kleinergleich, signed/unsigned) und einen Satz 
Branch-Mnemonics für die Flags.

Und wenn man sich die Mnemonics jederzeit herleiten kann, weil der 
Assembler alle Möglichkeiten kennt, dann brauche ich mir die auch nicht 
einprägen.

> Zufällig hatte ich mal einen Atari800XL, den ich natürlich auch
> in Assembler programmiert habe. Und das Gute war bei dem Ding gerade,
> dass eine 1:1-Beziehung zwischen Mnemnonic und OpCode bestand.

Das hängt schlicht von deinem Assembler ab. Verschiedene Assembler haben 
verschiedene Mnemonics, auch auf der gleichen/kompatiblen Architektur 
(vgl. 8085- vs. Z80-Mnemonics, Intels 8086-Assembler im 
8085-Kompatiblitätsmodus, oder Intel vs. AT&T auf x86).

> Gab's eigentlich beim 68k-Assembler solche redundanten
> Pseudo-Instruktionen? Kann mich nicht mehr 100%ig erinnern,
> aber ich bin fast sicher: nein, diesen Schwachsinn
> gab es dort auch nicht.

Wenn das Instruktion Set vollkommen orthogonal ist, dann hast du sogar 
verschiedene Opcodes (und damit verschiedene Mnemonics) für die gleiche 
Funktionalität...

: Bearbeitet durch User
von LostInMusic (Gast)


Lesenswert?

>ROL Rn = ADC Rn,Rn

Dann dürfte das die komplette (?) Liste sein:
1
CLR (→ EOR)
2
SER (→ LDI)
3
4
SBR (→ ORI) 
5
CBR (→ ANDI)
6
7
LSL (→ ADD) 
8
ROL (→ ADC) 
9
10
TST (→ AND)
11
12
SEC, SEN, SEZ, SEI, SES, SEV, SET, SEH (→ BSET)
13
CLC, CLN, CLZ, CLI, CLS, CLV, CLT, CLH (→ BCLR)
14
15
BREQ, BRCS, BRSH, BRMI, BRGE, BRHS, BRTS, BRVS (→ BRBS)
16
BRNE, BRCC, BRLO, BRPL, BRLT, BRHC, BRTC, BRVC (→ BRBC)

von P. M. (mikro23)


Lesenswert?

LostInMusic schrieb:
> Dann dürfte das die komplette (?) Liste sein:

Fast:

BRCS = BRLO
BRCC = BRSH

BRCS/LO, BREQ, BRMI, BRVS, BRLT, BRHS, BRTS, BRIE (→ BRBS)
BRCC/SH, BRNE, BRPL, BRVC, BRGE, BRHC, BRTC, BRID (→ BRBC)

von Jobst M. (jobstens-de)


Lesenswert?

Schon witzing, worüber sich Atmel so Gedanken gemacht hat.
Schlimmer, worüber man sich keine Gedanken gemacht hat:

Es geht hierbei um die Befehle: LD, LDI, ST, MOV, OUT, IN
Hier wäre es meiner Meinung nach wichtig gewesen, dass der Assembler 
dies dem Programmierer gegenüber mit nur einem Befehl abbildet. Der 8051 
hat es mit MOV vorgemacht.
Der Assembler entscheidet anhand der Quellen/Ziele, welcher 
Maschinenbefehl benutzt wird.


Gruß

Jobst

von LostInMusic (Gast)


Lesenswert?

>BRCS = BRLO
>BRCC = BRSH

All right, thanks :-)

von LostInMusic (Gast)


Lesenswert?

Dann gibt es also insgesamt 7 + 2·8 + 2·9 = 41 Alias-Mnemonics:
1
CLR (→ EOR)
2
SER (→ LDI)
3
4
SBR (→ ORI) 
5
CBR (→ ANDI)
6
7
LSL (→ ADD) 
8
ROL (→ ADC) 
9
10
TST (→ AND)
11
12
SEC, SEN, SEZ, SEI, SES, SEV, SET, SEH (→ BSET)
13
CLC, CLN, CLZ, CLI, CLS, CLV, CLT, CLH (→ BCLR)
14
15
BRCS/LO, BREQ, BRMI, BRVS, BRLT, BRHS, BRTS, BRIE (→ BRBS)
16
BRCC/SH, BRNE, BRPL, BRVC, BRGE, BRHC, BRTC, BRID (→ BRBC)

Das Instruction Set Summary des ATMega 48/88/168 listet genau 111 
Mnemonics auf (wenn man die Varianten von LD, LDD, ST, STD und LPM nur 
einmal zählt). Damit beläuft sich der Anteil der redundanten auf ca. 37 
%.

von Rolf M. (rmagnus)


Lesenswert?

c-hater schrieb:
> Aber dann hatten sie eben die Zahl der tatsächlich unterstützten
> Instruktionen in's DB schreiben müssen, was marketingtechnisch halt
> nicht so gut gekommen wäre...

Also ich hab ja schon so manche Verschwörungstheorie gehört, aber das 
ist dann doch arg albern. Du glaubst allen Ernstes, dass Atmel sich 
mehrere Namen für die gleiche Instruktion ausgedacht hat, damit mehr 
Leute den AVR gegenüber anderen Architekturen bevorzugen, weil er mehr 
Instruktionen kennt? Offenbar hast du keine Ahnung, nach welchen 
Kriterien Entwickler ihre µCs auswählen.

> Unsinn. Zufällig hatte ich mal einen Atari800XL, den ich natürlich auch
> in Assembler programmiert habe. Und das Gute war bei dem Ding gerade,
> dass eine 1:1-Beziehung zwischen Mnemnonic und OpCode bestand.

Das wäre jetzt auf meiner Liste der "Features" einer CPU-Architektur so 
ziemlich das letzte, was mich diese gegenüber einer anderen bevorzugen 
ließe.

Jobst M. schrieb:
> Schon witzing, worüber sich Atmel so Gedanken gemacht hat.
> Schlimmer, worüber man sich keine Gedanken gemacht hat:
>
> Es geht hierbei um die Befehle: LD, LDI, ST, MOV, OUT, IN
> Hier wäre es meiner Meinung nach wichtig gewesen, dass der Assembler
> dies dem Programmierer gegenüber mit nur einem Befehl abbildet. Der 8051
> hat es mit MOV vorgemacht.

Ist beim x86 ja auch so. Da fand ich das aber irgendwie blöd, dass 
bestimmt ein Dutzend eigentlich verschiedene Befehle alle den selben 
Namen hatten.

von Soul E. (Gast)


Lesenswert?

c-hater schrieb:

>> Beispiel 6502: da gibt es einen bedingten Sprung, der bei gesetztem
>> Carry-Flag genommen wird. Den kann man jetzt wahlweise als
>>
>>
1
>> BCS label
2
>>
>> oder
>>
1
>> BGE label
2
>>
>>
>> schreiben.
>
> Unsinn. Zufällig hatte ich mal einen Atari800XL, den ich natürlich auch
> in Assembler programmiert habe.

Tja, hättest Du mal ein bisschen gespart und Dir einen Apple ][ 
geleistet. Da hat eigentlich jeder Assembler BLT (Branch on Less Than) 
and BGE (Branch on Greater than or Equal) als Synonym für BCC und BCS 
akzeptiert. Und Apple hat diese in ihren Quellcodes (die damals ja noch 
in den Handbüchern abgedruckt waren) auch verwendet.

von Dr. Sommer (Gast)


Lesenswert?

Jobst M. schrieb:
> Hier wäre es meiner Meinung nach wichtig gewesen, dass der Assembler
> dies dem Programmierer gegenüber mit nur einem Befehl abbildet.

Die sind aber unterschiedlich schnell. Zudem ist es grundlegende 
Charakteristik einer RISC & Load-Store-Architektur, dass die eben 
nicht gleich sind, und man für Speicher Zugriffe extra Befehle.hat.

von Jobst M. (jobstens-de)


Lesenswert?

Dr. Sommer schrieb:
> Die sind aber unterschiedlich schnell. Zudem ist es grundlegende
> Charakteristik einer RISC & Load-Store-Architektur, dass die eben
> nicht gleich sind, und man für Speicher Zugriffe extra Befehle.hat.

Ich denke, Du hast die Problematik nicht verstanden, denn der Controller 
sieht ja gar keinen Unterschied. Es geht um den Assembler. Das Programm 
auf dem PC, welches Dein Programm in Maschinenbefehle umsetzt.
Ich finde, dieses sollte mir die Arbeit abnehmen, aus
 MOV PORTD, R3 -> OUT PORTD, R3
 MOV R16, #7 -> LDI R16, 7
 MOV TWSR, temp -> STS TWSR, temp
 MOV R3, R4 -> MOV R3, R4
zu machen.


Gruß

Jobst

von Dr. Sommer (Gast)


Lesenswert?

Jobst M. schrieb:
> denn der Controller sieht ja gar keinen Unterschied.

Zumindest der AVR Controller sieht einen dramatischen Unterschied 
zwischen mov, ldr, in. Und dieser wird nunmal auch in der Assembler 
Sprache abgebildet, genau wie beim ARM. Nicht zuletzt um zu sehen welche 
der grundverschiedenen Instruktionen genutzt werden und somit wie 
schnell diese sind...
Zumal kann man auch Zahlen statt der Register/Adress Aliase übergeben, 
und dann ist völlig unklar welche Instruktion jetzt tatsächlich gemeint 
ist.

Aber anstelle über so etwas zu diskutieren kann man auch einfach 
richtige Programmiersprachen wie C++ benutzen und so einen Unsinn dem 
Compiler überlassen.

von Jobst M. (jobstens-de)


Lesenswert?

Dr. Sommer schrieb:
> Aber anstelle über so etwas zu diskutieren

Was machst Du dann hier?


Du hast es immernoch nicht verstanden.


Gruß

Jobst

von (prx) A. K. (prx)


Lesenswert?

Man kann unterschiedliche Operanden-Typen einer gleichartigen Operation 
über verschiedene Mnemonics unterscheiden (8080 Assembler), oder über 
verschiedene Darstellungen der Operanden (Z80 Assembler). An den 
Befehlen ändert das nichts. Und wie üblich wird es unterschiedliche 
Geschmäcker geben. Also ob man es lieber für jeden Opcode getrennt hat, 
oder vereinheitlicht.

von Rolf M. (rmagnus)


Lesenswert?

A. K. schrieb:
> Und wie üblich wird es unterschiedliche
> Geschmäcker geben. Also ob man es lieber für jeden Opcode getrennt hat,
> oder vereinheitlicht.

Jo, und es läßt sich schon vortrefflich darüber streiten, ob ein 
Register in ein anderes kopieren, einen Immediate-Wert in ein Register 
laden und ein Speicherzugriff als gleichartige Operationen gelten 
sollten oder nicht.
Wem die verschiedenen Mnemonics zu viel sind, der kann ja einen 
OISC-Prozessor nehmen ;-)
https://en.wikipedia.org/wiki/One_instruction_set_computer

von Andreas B. (bitverdreher)


Lesenswert?

Rolf M. schrieb:
> Wem die verschiedenen Mnemonics zu viel sind, der kann ja einen
> OISC-Prozessor nehmen ;-)
> https://en.wikipedia.org/wiki/One_instruction_set_computer

Dafür kann man dann ja Makros schreiben. ;-)

Gruß
Andreas

von C. A. Rotwang (Gast)


Lesenswert?

Kaj G. schrieb:

> Es scheinen ein paar Opcodes mehrfach belegt zu sein, z.B. haben die
> ASM-Befehle BRBC und BRCC den selben Opcode.


Kann es sein das die Begriffe Mnemonic und Opcode verwechselst? 
Assemblersprache und OpCode ist nicht dasgleiche. Schau mal: 
https://de.wikipedia.org/wiki/Assemblersprache#Beschreibung

von Kaj (Gast)


Lesenswert?

C. A. Rotwang schrieb:
> Kann es sein das die Begriffe Mnemonic und Opcode verwechselst?
Nein.

Lass es mich anders formulieren:
Aus Mnemonic A wird           Opcode X erzeugt.
Aus Mnemonic B wird ebenfalls Opcode X erzeugt.

Sprich:
Ein Opcode wird von zwei oder mehr Mnemonics belegt -> 
doppelte/mehrfache belegung des Opcodes.

von S. R. (svenska)


Lesenswert?

Kaj schrieb:
> Ein Opcode wird von zwei oder mehr Mnemonics belegt ->
> doppelte/mehrfache belegung des Opcodes.

"Orange" und "Apfelsine" sind zwei Mnemonics für die gleiche Frucht. 
Deswegen ist die Frucht noch lange nicht doppelt belegt.

von LostInMusic (Gast)


Lesenswert?

>"Orange" und "Apfelsine" sind zwei Mnemonics für die gleiche Frucht.
>Deswegen ist die Frucht noch lange nicht doppelt belegt.

Ähhh......? <irritiertbin> Was verstehst Du denn dann unter einer 
Namens-Doppelbelegung?

Kannst Du mal ein Beispiel angeben, wo Deiner Meinung nach irgendwas 
durch Namen/Mnemonics doppelt belegt ist?

von Soul E. (Gast)


Lesenswert?

S. R. schrieb:

> "Orange" und "Apfelsine" sind zwei Mnemonics für die gleiche Frucht.
> Deswegen ist die Frucht noch lange nicht doppelt belegt.

Im Sinne des TO schon. Exakt darum ging es -- zwei verschiedene 
Namenswörter beschreiben den gleichen Zustand.

von Michael U. (amiga)


Lesenswert?

Hallo,

ASM-Mnemotics sind Merkhilfen.
Die CPU-hersteller haben für Ihre Assembler versucht, möglichst merkbare 
Abkürzungen zu finden. Kurz mußten sie auch noch sein, Speicherplatz für 
den Sourcecode war knapp.
65xx und Z80 sind da eben völlig verscheidene Wege gegangen. Bei waren 
Merkbar, man hat sich daran gewöhnt.

Ob LDI für load immediate nun merkbarer ist als LD für load und das 
nachschauen, was geladen wird weil # vor dem Operanden steht, mag jeder 
selbst entscheiden.
mov hat mich eigentlich immer gestört, war bei mir gedanklich immer 
näher an verschieben als an kopieren.

Wenn ich scheiben oder rotieren will, will ich einen ROL, ROR, LSL usw. 
haben und mir nicht den Kopf darüber zerbrechen, ob es mit EOR x,x oder 
ADD x,x ober SUB x,x ja auch ginge.

Naja, inzwuschen muß man ja eher auf Klammerei und vergessene Semikolon 
achten. ;)

Gruß aus Berlin
Michael

von Thomas E. (picalic)


Lesenswert?

Michael U. schrieb:
> Wenn ich scheiben oder rotieren will, will ich einen ROL, ROR, LSL usw.
> haben und mir nicht den Kopf darüber zerbrechen, ob es mit EOR x,x oder
> ADD x,x ober SUB x,x ja auch ginge.

Vor Allem will ich aber beim ROL oder ASL auch nur Z und C beeinflusst 
wissen, und nicht irgenwelche anderen Nebenwirkungen, die noch nicht mal 
im Datenblatt stehen! (Super, ATMEL!)

von (prx) A. K. (prx)


Lesenswert?

Michael U. schrieb:
> Die CPU-hersteller haben für Ihre Assembler versucht, möglichst merkbare
> Abkürzungen zu finden.

Nicht immer.

NEC hat für die V20/30/... Varianten von Intels 8086er Serie einen 
komplett eigenen Befehlssatz ersonnen, was Mnemonics und Registernamen 
betrifft. Möglicherweise aus Sorge um Urheberrecht, oder sowas in der 
Art. Hat natürlich nie jemand genutzt, aber das musste offenbar mit 
Gewalt anders sein.

Zilog hatte sich davor auch schon bemüht, sich von Intels 8080 
Bezeichnungen abzuheben. Hier sind die Motive nicht ganz so eindeutig, 
weil das Ergebnis summarum klar besser ist. Aber wer nennt einen 
Store-Befehl schon Load (LD), wenn ihm kein Anwalt im Genick sitzt?

> Wenn ich scheiben oder rotieren will, will ich einen ROL, ROR, LSL usw.
> haben

Wobei ROL/ROR etwas hakt, weil sich aus dem Mnemonic nicht erschliesst, 
ob das Carry-Flag Teil der Runde ist oder nicht. Das ist je nach CPU mal 
so mal so.

von Falk B. (falk)


Lesenswert?

@ Thomas Elger (picalic)

>Vor Allem will ich aber beim ROL oder ASL auch nur Z und C beeinflusst
>wissen, und nicht irgenwelche anderen Nebenwirkungen, die noch nicht mal
>im Datenblatt stehen! (Super, ATMEL!)

Welche denn? Das H-Flag, da so oder so bestenfalls in hömiopatischen 
Dosen für BCD-Arithmetik genutzt wird?

von (prx) A. K. (prx)


Lesenswert?

Thomas E. schrieb:
> Vor Allem will ich aber beim ROL oder ASL auch nur Z und C beeinflusst
> wissen,

Mit solcher Minimalistik hatte sich Intel gründlich in die Scheisse 
geritten. Es ist schon schlimm genug, dass jeder Befehl einen anderen 
Set aus insgesamt 3 Flag-Gruppen beeinflusst. Aber um das Mass voll zu 
machen sind die auch auf die exquisit bescheuerte Idee verfallen, ein 
Flag bei Shifts nur dann zu verändern, wenn die Anzahl nicht 0 ist.

Denn sobald man Befehle nicht mehr streng im Gänsemarsch ausführt, 
wächst die Komplexität der Flagverarbeitung durch solche Mätzchen massiv 
an und man erhält unbeabsichtigte Abhängigkeiten von Befehlen. Das hat 
beispielsweise alten Code beim Pentium 4 bös verlangsamt und mancher x86 
hat bei Shifts mit n=0 den Befehl gleich zweimal ausgeführt - das erste 
Mal in der Annahme n!=0 und das zweite mal viel langsamer aber richtig.

Also wenn schon Flags, dann alle oder keines, wenn man nicht bloss bis 
zum nächsten Laternenmast denkt.

: Bearbeitet durch User
von Paul B. (paul_baumann)


Lesenswert?

Michael U. schrieb:
> Wenn ich scheiben oder rotieren will, will ich einen ROL, ROR, LSL usw.
> haben...

Wenn ich etwas bei den Assemblermnemonics vermisse, dann sind es ROFL 
und LOL.
:)
MfG Paul

von (prx) A. K. (prx)


Lesenswert?

Paul B. schrieb:
> Wenn ich etwas bei den Assemblermnemonics vermisse, dann sind es ROFL
> und LOL.

Tröste dich, beim 1802 und den 6800ern gibt es dafür SEX!
Aber das waren eben die liberalen 70er, da konnte man noch.

: Bearbeitet durch User
von C. A. Rotwang (Gast)


Lesenswert?

Kaj schrieb:
> C. A. Rotwang schrieb:
>> Kann es sein das die Begriffe Mnemonic und Opcode verwechselst?
> Nein.
>
> Lass es mich anders formulieren:
> Aus Mnemonic A wird           Opcode X erzeugt.
> Aus Mnemonic B wird ebenfalls Opcode X erzeugt.
>
> Sprich:
> Ein Opcode wird von zwei oder mehr Mnemonics belegt ->
> doppelte/mehrfache belegung des Opcodes.

Nein aus einem Mnemonic wird nichts erzeugt, du darfst das nicht mit 
einem Compiler verwechseln.

Etwas Geschichte:
Bei den ersten CPUS würde nicht mit assembler gearbeitet sondern direkt 
gecodet. Mit einem Monitorprogramm hat man die Programmcode - die 
Hexzahlen an die gewünschte Speicheraddressen geschrieben. Es war im ROM 
und RAM einfach nicht genüg Platz für einen Assembler. Die Mnemonics hat 
man nur verwendet um den Code in lesbarer Form festzuhalten. Die 
Programmierer damals haben den code dann per tabelle (reference card) 
oder im Kopf umgesetzt . Beispiel für eine solche Tabelle dort: 
http://www.ballyalley.com/ml/z80_docs/Z80_Instant_Reference_Card.pdf

Zu dieser Zeit war ein "aufgeräumter" Befehlssatz und gute Mnemonics 
extrem wichtig, denn nur so kann man Fehlerarm im Kopf assemblieren. 
Irgendwo hab ich mal von einen Prozessor gelesen, dessen Vorteil 
gegenüber den Vorgänger in einer Änderung der Memonic betstands. Deteils 
find ich grad nicht, vielleicht war es die Trennung von alles MOV auf 
MOV und LOAD je nach Quelloperand (register oder Mem subsystem) was es 
deutlich einfacher macht die Ausführungszeit der Code-abschnitte 
abzuschätzen.

Irgendwann hatte man die Hardware für brauchbare Assembler, insbesonders 
die sogenannten Makro-assembler. Daraus hat sich dann eine 
Assemblersprache entwickelt die im gewissen Sinne Architektur-unabhängig 
ist. beispielsweise GNU-Assembler 
https://sourceware.org/binutils/docs/as/GNU-Assembler.html#GNU-Assembler 
Bei denen besteht nun die Möglichkeit die operation etwas "allgemeiner" 
und leicht verständlicher zu formulieren". Man muss nun also nicht mehr 
wissen, od der Prozesor "Bit - set" oder "bit clear" oder "bit - load" 
oder "AND -immediate" Operationen unterstützt. Der Cross-Platform 
assembler bastelt selbst daraus die passenden Codes.

Der Opcode ist also keinesfalls mehrfach belegt wie im Sinne einer 
mehrfachen Tastbelegung (je nach Context (Status 
SHIFT/WIN/Ctrl/ALTGr-Taste) andere "ergebniss"). Es wird (beim AVR) 
immer der selbe Opcode auf die selbe Weise ausgeführt egal wie der 
Mnemonic dazu lautet.

(Einschränkung: es gibt allerdings prozessoren  bei denen der OPcode 
contextabhängig unterschiedlich ausgeführt wird, beispiels 
priviliegierte Befehle die im Supervisor-mode ordentlich abgearbeitet 
werden, aber im User-Mode zu eine Exception führen - da )

von Soul E. (Gast)


Lesenswert?

C. A. Rotwang schrieb:

> Nein aus einem Mnemonic wird nichts erzeugt, du darfst das nicht mit
> einem Compiler verwechseln.

Ein Assembler erzeugt aus einem Mnemonic einen Opcode. Genau dafür ist 
er da.

Du tippst in Deiner Assembler-Source die Mnemonics "MOV Status1, A" ein 
und der Assembler erzeugt daraus im Hexfile den Opcode "F5 35".

Und selbstverständlich kann man für einen Opcode mehrere verschiedene 
Mnemoics verwenden. Es gibt sogar Assembler, die Macro-Definitionen 
erlauben. Da kannst Du den MOV-Befehl Horst und den JMP-Befehl Uwe 
nennen. Und Horst und Uwe liefern trotzdem die gleiche Opcodes im 
Hexfile wie MOV und JMP.

von Blügan (Gast)


Lesenswert?

A. K. schrieb:
> Paul B. schrieb:
>> Wenn ich etwas bei den Assemblermnemonics vermisse, dann sind es ROFL
>> und LOL.
>
> Tröste dich, beim 1802 und den 6800ern gibt es dafür SEX!
> Aber das waren eben die liberalen 70er, da konnte man noch.

Da musst Du jetzt aber sehr traurig sein.

von Possetitjel (Gast)


Lesenswert?

soul e. schrieb:

> Und selbstverständlich kann man für einen Opcode mehrere
> verschiedene Mnemoics verwenden. Es gibt sogar Assembler,
> die Macro-Definitionen erlauben. Da kannst Du den MOV-Befehl
> Horst und den JMP-Befehl Uwe nennen. Und Horst und Uwe
> liefern trotzdem die gleiche Opcodes im Hexfile wie MOV
> und JMP.

Genau deshalb ist die Ursprungsfrage unsinnig.

Die CPU muss nix unterscheiden, denn sie soll ja immer
genau das gleiche machen.

Da die genau gleiche Operation aber in unterschiedlichem
Kontext verschiedene Bedeutung haben kann, möchte der
Mensch der Bedeutung angepasste - also verschiedene  -
Namen für dieselbe Sache haben.

von C. A. Rotwang (Gast)


Lesenswert?

soul e. schrieb:
> C. A. Rotwang schrieb:
>
>> Nein aus einem Mnemonic wird nichts erzeugt, du darfst das nicht mit
>> einem Compiler verwechseln.
>
> Ein Assembler erzeugt aus einem Mnemonic einen Opcode. Genau dafür ist
> er da.

Ich beziehe mich auf die Zeit vor dem Assembler, Mnemonics gab es 
bereits bevor es Assembler gab. Mnemonics und assembler code code ist in 
meiner Betrachtung nicht dasselbe, insbesnonders wenn man den Schritt zu 
crossplattform assembler macht. Der feine Unterschied zwischen Mnemonics 
wird von Jungspunden die einen Hex-Monitor nicht von einem 4k-Monitor 
unterscheiden können, gern missachtet.

von c-hater (Gast)


Lesenswert?

Falk B. schrieb:

> Welche denn? Das H-Flag, da so oder so bestenfalls in hömiopatischen
> Dosen für BCD-Arithmetik genutzt wird?

Echte Assemblerprogrammierer nutzen das Halfcarry natürlich immer dann, 
wenn es sich zur Nutzung förmlich anbietet. Und das passiert auch 
abseits der BCD-Arithmetik durchaus des öfteren mal...

Manchmal ist es sogar so: Man organisiert Daten absichtlich so, dass das 
H-Flag sich taktsparend einsetzen läßt. Typisches Beispiel hierfür wären 
DoubleBuffer-Mechanismen mit Buffern <= 16 Elementen. Nicht gerade 
selten und obendrein recht häufig im exklusiven Teil von ISRs verwendet, 
wo jeder einzelne verschissene gesparte Takt vielfach zählt, weil er die 
Performance und Latenz des Gesamtsystems runterzieht.

Aber ja, für Heizungsteuerungen u.ä. kann man auch problemlos drauf 
verzichten...

von Rolf M. (rmagnus)


Lesenswert?

Thomas E. schrieb:
> Michael U. schrieb:
>> Wenn ich scheiben oder rotieren will, will ich einen ROL, ROR, LSL usw.
>> haben und mir nicht den Kopf darüber zerbrechen, ob es mit EOR x,x oder
>> ADD x,x ober SUB x,x ja auch ginge.
>
> Vor Allem will ich aber beim ROL oder ASL auch nur Z und C beeinflusst
> wissen,

Warum?

> und nicht irgenwelche anderen Nebenwirkungen, die noch nicht mal im
> Datenblatt stehen! (Super, ATMEL!)

Das ist alles haarklein im AVR Instruction Set Manual beschrieben. Atmel 
hat sich nur dagegen entschieden, dessen Inhalt komplett in jedes 
einzelne Datenblatt zu kopieren - in der Annahme, die Benutzer wären 
intelligent genug, das auch so zu finden.

von Thomas E. (picalic)


Lesenswert?

Ok, WELCHE Flags beeinflusst werden sollten oder nicht, scheint jeder 
etwas anders zu sehen. Für mich wäre ein Schiebe-Befehl eben in erster 
Linie ein Schiebebefehl und keine Addition mit sich selbst. Wenn Atmel 
meint, den Additionsbefehl dafür verwenden zu müssen, um Opcodes zu 
sparen, habe ich aber nichts degegen, wenn sie es RICHTIG dokumentieren.

Rolf M. schrieb:
> Das ist alles haarklein im AVR Instruction Set Manual beschrieben. Atmel
> hat sich nur dagegen entschieden, dessen Inhalt komplett in jedes
> einzelne Datenblatt zu kopieren - in der Annahme, die Benutzer wären
> intelligent genug, das auch so zu finden.

Dann sollten sie es konsequent aus dem Datenblatt 'raushalten, statt in 
jedem einzelnen Datenblatt eine offenbar falsche Kombination an 
beeinflussten Status-Flags anzugeben. Als Entwickler möchte ich mich auf 
gemachte Angaben in der original-Doku des Herstellers verlassen können 
und nicht an verschiedenen Stellen suchen müsen, ob da noch etwas 
anderes steht!

von Rolf M. (rmagnus)


Lesenswert?

Thomas E. schrieb:
> Dann sollten sie es konsequent aus dem Datenblatt 'raushalten, statt in
> jedem einzelnen Datenblatt eine offenbar falsche Kombination an
> beeinflussten Status-Flags anzugeben.

Ich hab mal exemplarisch das vom ATMEGA8 geöffnet, und da scheint bei 
mehreren Instruktionen die Liste der beeinflussten Flags fehlerhaft zu 
sein. Du hast natürlich recht, dass das nicht so sein sollte.

von Thomas E. (picalic)


Lesenswert?

Etwas befremdlich finde ich auch, daß in der Befehlsreferenz bei 
Befehlen, wie "BRLT", "BRGE" usw., knallhart vorgegaukelt wird, der 
Befehl würde das N und V Flag miteinander verknüpfen. In Wahrheit wird 
aber natürlich nur das S-Flag geprüft. Ich würde mir von einer Referenz 
eher technische Fakten wünschen, als diese Verschleierung...

von S. R. (svenska)


Lesenswert?

C. A. Rotwang schrieb:
> Ich beziehe mich auf die Zeit vor dem Assembler, Mnemonics gab es
> bereits bevor es Assembler gab.

Dann erklär mal einem Jungspund die Steinzeit, bitte.

Meine Welt sagt: Ein Opcode beschreibt einen Befehl der CPU, und ein 
Mnemonic ist eine menschenfreundliche Merkhilfe für diesen Opcode. "NOP" 
ist einfacher zu merken als "F9" und kürzer als "No OPeration".

> Mnemonics und assembler code code ist in meiner Betrachtung nicht
> dasselbe, insbesnonders wenn man den Schritt zu
> crossplattform assembler macht.

Was soll denn bitte Crossplattformassembler sein? Der kleinste 
gemeinsame Nenner aus Z80, x86 und 6502?

von Nop (Gast)


Lesenswert?

S. R. schrieb:
> Was soll denn bitte Crossplattformassembler sein?

Das nennt sich sehr prägnant "C".

SCRN. :-)

von Jobst M. (jobstens-de)


Lesenswert?

S. R. schrieb:
> Was soll denn bitte Crossplattformassembler sein? Der kleinste
> gemeinsame Nenner aus Z80, x86 und 6502?

Es gab Compiler, welche Maschinencode von CPU A auf Maschinencode vom 
CPU B übersetzten.


Gruß

Jobst

von (prx) A. K. (prx)


Lesenswert?

Jobst M. schrieb:
> Es gab Compiler, welche Maschinencode von CPU A auf Maschinencode vom
> CPU B übersetzten.

Maschinencode != Assembler. Als dynamic code translation ist das sehr 
aktuell.

Beim 8086 gab es die Möglichkeit, 8080 Asm-Code auf 8086 Code 
umzusetzen, weil die 8086 passend gebaut war. Weiss aber nicht, ob das 
ein Asm war, oder ein Umsetzprogramm auf Quelltextebene

Ein Assembler, der die Befehle auf verschiedene Zielmaschinen umsetzt, 
ist aber allenfalls dort sinnvoll, wo eine enge Verwandschaft besteht. 
Also die exakt gleichen Befehle in verschiedenen Modellen 
unterschiedlich codiert sind.

: Bearbeitet durch User
von Jobst M. (jobstens-de)


Lesenswert?

A. K. schrieb:
> Also die exakt gleichen Befehle in verschiedenen Modellen
> unterschiedlich codiert sind.

Etwas komplexer war das schon ...
Eine einfache 1:1 Umsetzung war das nicht.

Wenn auf der Zielplattform für die selbe Aufgabe 2 Befehle nötig waren, 
welche auf der Quellplattform mit nur einem Befehl erledigt wurde, dann 
wurden das eben 2 Befehle. Und umgekehrt.


Gruß

Jobst

von C. A. Rotwang (Gast)


Lesenswert?

S. R. schrieb:
> C. A. Rotwang schrieb:

> Was soll denn bitte Crossplattformassembler sein? Der kleinste
> gemeinsame Nenner aus Z80, x86 und 6502?

Der Gnu-assembler ist beispielsweise ein crossplattformassembler, er er 
verwndwt sog. Pseudo-Ops und direktiven für Architekturabhängigkeiten 
(machine-dependencies) 
https://sourceware.org/binutils/docs/as/GNU-Assembler.html#GNU-Assembler

Bei ARM ist es nicht viel anders, anders als allgemein bekannt gibt es 
über die verschiedenen ARM-familien erhebliche Unterschiede in der 
Architektur, oder alternative Befehlssätze (THUMB) deshalb hat sich ARM 
die Unified Assembly Language -> UAL einfallen lassen.

Ein crossplatform asembler verwendet also im Kern einen Assemblersprache 
die sich auf die jeweiligen instruction sets 1:1 abbilden lässt plus 
direktiven für die maschinen-extras. das Userinterface (bspw. command 
line options/Fileformate) ist auch möglichst gleich.

Das kann mensch beispielsweise ganz gut an den GNU-toolchains für avr 
und arm sehen.

von C. A. Rotwang (Gast)


Lesenswert?

S. R. schrieb:
> C. A. Rotwang schrieb:
>> Ich beziehe mich auf die Zeit vor dem Assembler, Mnemonics gab es
>> bereits bevor es Assembler gab.
>
> Dann erklär mal einem Jungspund die Steinzeit, bitte.

Die Jugend lässt sich nach meiner Erfahrung nichts erklären, die Jugend 
nutz google oder stirb dumm. Also schlau machen musst du dich schon 
selber, genügend Literatur zu Thema Computerarchitektur gibt es. Mein 
Empfehlung Patterson, Hennessy,

>
> Meine Welt sagt: Ein Opcode beschreibt einen Befehl der CPU, und ein
> Mnemonic ist eine menschenfreundliche Merkhilfe für diesen Opcode. "NOP"
> ist einfacher zu merken als "F9" und kürzer als "No OPeration".

Schau dir einfach mal einen Arithmetik befehl und die möglichen 
adressierungen an, dann sollte klar werden das das Mnemonic mehr ist als 
eine Merkhilfe sondern eine Menge über die zugrundeliegende Architektur 
verrät (addressierung der Register) mit einen gut formulierten memonic 
kann man sich die Instruction gut im Kopf zusammenbassteln, fiktives 
Beispiel

MOV r1, r15 -> "101010" "00"  "0001" "1111"   -> 651f;

also OpCode für Move & Befehlsmodifikator & Adresse dest & Adresse 
source

von (prx) A. K. (prx)


Lesenswert?

S. R. schrieb:
> Dann erklär mal einem Jungspund die Steinzeit, bitte.

https://en.wikipedia.org/wiki/MIX

Sieht aus wie ein Aprilscherz, war aber keiner. Noch Anfang der 80er war 
das ein gängiger Weg, Inf-Studenten Assembler beizubringen.

Das Teil ist frühen Architekturen durchaus nahe, also circa jenen vor 
IBM 360. Die bin/dez Doppelnatur widerspiegelt das, denn es gab anfangs 
beides, binäre und dezimale Maschinen. Der erste in relativ grossen 
Stückzahlen verkaufte Computer war dezimal (IBM 650), obwohl bereits 
Zuse binär arbeitete.

: Bearbeitet durch User
von Axel S. (a-za-z0-9)


Lesenswert?

C. A. Rotwang schrieb:
>> Meine Welt sagt: Ein Opcode beschreibt einen Befehl der CPU, und ein
>> Mnemonic ist eine menschenfreundliche Merkhilfe für diesen Opcode. "NOP"
>> ist einfacher zu merken als "F9" und kürzer als "No OPeration".
>
> Schau dir einfach mal einen Arithmetik befehl und die möglichen
> adressierungen an, dann sollte klar werden das das Mnemonic mehr ist als
> eine Merkhilfe sondern eine Menge über die zugrundeliegende Architektur
> verrät (addressierung der Register) mit einen gut formulierten memonic
> kann man sich die Instruction gut im Kopf zusammenbassteln,

Zum einen sagst du hier ziemlich genau das gleiche wie dein Vorredner - 
Mnemonics werden so designt, daß sie sich leicht merken und verstehen 
lassen. Was übrigens schon im Wort steckt: 
https://de.wikipedia.org/wiki/Mnemonic

Zum zweiten ist es einen Binsenweisheit, daß Mnemonics Besonderheiten 
der Architektur widerspiegeln, denn sie werden ja gezielt für die 
Zielarchitektur entwickelt. Eine Architektur, bei der immer der Akku das 
Ziel einer ALU-Operation ist, wird bspw. für ALU-Operationen immer nur 
einen (oder gar keinen) Operand benötigen. Eine Architektur ohne Stack 
hat keine PUSH und POP Mnemonics. etc. pp.

Zum dritten widerspreche ich deiner Behauptung:

C. A. Rotwang schrieb:
> Ich beziehe mich auf die Zeit vor dem Assembler, Mnemonics gab es
> bereits bevor es Assembler gab.

Denn Mnemonics sind für die (damals neue) Technik der Assembler- 
programmierung entwickelt worden. Und das Merkmal dieser Technik ist nun 
mal, daß das Programm als Aufreihung von Mnemonics geschrieben und dann 
automatisiert -von einem Assembler- in Maschinensprache übersetzt wird.

Weder Assembler noch Mnemonics sind älter als der jeweils andere. Die 
Existenz des einen ist Grundlage für die Existenz des anderen. Die 
Mnemonics als symbolische Beschreibung der Möglichkeiten einer 
Prozessorarchitektur sind weitgehend nutzlos, wenn es keinen Assembler 
gibt, der sie in Maschinencode übersetzt. Und ein Assembler ist 
weitgehend nutzlos, wenn er nicht die Mnemonics wenigstens einer 
Zielarchitektur implementiert.

PS: weil abzusehen ist, daß dieser Einwand kommt: aus dem von mir 
gesagten geht hervor, daß Mnemonics in einen gewissen Sinn natürlich vor 
dem Assembler existieren müssen, der sie implementiert. Auch wieder eine 
Binsenweisheit. Aber ich dachte ich sage es wieder explizit, bevor 
jemand versucht, daraus einen Widerspruch zu konstruieren.

: Bearbeitet durch User
von (prx) A. K. (prx)


Lesenswert?

Axel S. schrieb:
> Eine Architektur, bei der immer der Akku das
> Ziel einer ALU-Operation ist, wird bspw. für ALU-Operationen immer nur
> einen (oder gar keinen) Operand benötigen.

In vielen früheren Architekturen wurde ein Operand im Mnemonic 
angegeben. Auch Akku-Architekturen haben meist mehrere Register, weil 
man schon sehr früh den Wert mehrerer Indexregister erkannte. In dieser 
Tradition steht 6800/6500, bei denen eben nicht die generische Form
  INC X
  MOV Y,A
definiert wurde, sondern deutlich kryptischer
  INX
  TAY

Heute neigt man eher zur generischen lesbareren Form. Das Mnemonic 
definiert die Operation, irgendwelche Operanden folgen dahinter. Solche 
Assemblersprache ist auch dann leidlich verständlich, wenn man der 
Architektur zum ersten Mal begegnet. Beispielsweise bei Lektüre fremden 
Codes - Wartbarkeit ist wichtiger als Sparsamkeit bei Quellcode-Bytes.

In diesem Sinn ist auch Zilogs Neudefinition der Assemblersprache im 
Rahmen der Z80 als Fortschritt zu sehen. Das ist klar übersichtlicher 
als Intels Minimalistik bei der 8080 CPU.

: Bearbeitet durch User
von S. R. (svenska)


Lesenswert?

C. A. Rotwang schrieb:
>> Meine Welt sagt: Ein Opcode beschreibt einen Befehl der CPU, und ein
>> Mnemonic ist eine menschenfreundliche Merkhilfe für diesen Opcode. "NOP"
>> ist einfacher zu merken als "F9" und kürzer als "No OPeration".
>
> Schau dir einfach mal einen Arithmetik befehl und die möglichen
> adressierungen an, dann sollte klar werden das das Mnemonic mehr ist als
> eine Merkhilfe sondern eine Menge über die zugrundeliegende Architektur
> verrät (addressierung der Register)

Die Mnemonics gehören zu einer bestimmten Architektur, insofern sollte 
es nicht überraschen, dass sie etwas über diese Architektur aussagen...

Auch, wenn viele Architekturen gleichlautende Mnemonics kennen (NOP, 
ADD, ...), sind es nicht die gleichen Mnemonics, denn sie funktionieren 
unterschiedlich.

> mit einen gut formulierten memonic kann man sich die Instruction
> gut im Kopf zusammenbassteln, fiktives Beispiel
>
> MOV r1, r15 -> "101010" "00"  "0001" "1111"   -> 651f;
>
> also OpCode für Move & Befehlsmodifikator & Adresse dest & Adresse
> source

Du vermischst Mnemonic und Codierung eines Befehls. Ein Mnemonic wie in 
deinem Beispiel sagt über die Codierung schlicht nichts mehr aus.

"MOV r1, 15" und "MOV r1, r15" nutzen zwei verschiedene Formate, und es 
ist nicht zwingend, dass "r1" an der gleichen Stelle im Bitstrom gleich 
codiert wird.

Weder muss die Codierung eines Befehls eindeutig sein (zwei Bitsequenzen 
dürfen auch dasselbe tun), noch muss ein Befehl eindeutig einem Mnemonic 
zugeordnet werden können (Pseudobefehle).

C. A. Rotwang schrieb:
> Die Jugend lässt sich nach meiner Erfahrung nichts erklären, die Jugend
> nutz google oder stirb dumm.

Ich wollte gerne wissen, wo deine Sichtweise anders ist als meine 
Sichtweise. Das kriege ich mit Google nicht raus. Muss ich wohl dumm 
sterben.

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.