Hallo Zusammen,
habe eine Frage zu den oben genannten Befehlen und zwar folgendes:
R1 = 0xfe
R2 = 0x03
Carry = 0
Z = 0
N = 1
V = 1
-----------------------------
Nun word folgendes ausgeführt: adc R1, R2
Als Ergebnis kommt 0x01 raus, aber ich möchte verstehen wie das
funktioniert, Der ADC Befehl addiert R1 und R2 miteinander. Aber wie
wird das Carry dazugerechnet? Wird es sozusagen dazuaddiert, dann würde
aber nicht 0x01 rauskommen. ODer addiert man R1 und R2 und schaut dann,
ob dann nach der Rechnung eine 1 davor ist oder nicht? Oder hängt das
damit zusammen, ob vorher das Carryfalg auf 0 wir in diesem Beispiel ist
oder auf 1.
Und was passiert bei add Befehl, wenn es zum Überlauf kommt, also was
würde für R1 herauskommen, wenn es add statt adc währe und wie würden
die Flags danach aussehen?
Danke vorab!
Mike schrieb:> Aber wie> wird das Carry dazugerechnet? Wird es sozusagen dazuaddiert, dann würde> aber nicht 0x01 rauskommen.
Doch, denn Carry ist ja (im Moment) 0. Es wird das Carryflag dazu
addiert, wie es vor der Rechnung existierte.
Dein gedankliches Problem liegt darin, dass die beiden Additionen
nicht nacheinander erfolgen, sondern praktisch gleichzeitig, d. h.
du hast einen Addierer mit drei Eingängen, von denen der dritte (das
Input-Carry) jedoch nur 1 Bit breit ist.
Nach der Operation wird dann der Zustand des Output-Carry in das
Carry-Flag des Prozessors übertragen.
(Selbst, falls die Operation in der Tat im Prozessor sequentiell
ausgeführt wird, dann wird durch Synchronisation sichergestellt,
dass das Input-Carry sich währed der Operation nicht mehr ändert.)
> Und was passiert bei add Befehl, wenn es zum Überlauf kommt, also was> würde für R1 herauskommen, wenn es add statt adc währe und wie würden> die Flags danach aussehen?
Die Flags würden ganz genauso aussehen. Die ADC-Operation unterscheidet
sich von ADD nur dann, wenn vorher das Carry-Flag ungleich 0 war.
ADD ignoriert in diesem Falle das Carry-Flag, ADC würde es mit
einbeziehen.
Die übliche Folge zum Addieren von Zahlen, die größer als die
Wortbreite des Prozessors sind, ist daher:
1
ADD R8, R4 ; hier interessiert der Zustand des Carry-Flags nicht,
2
; aber es wird durch die Operation gesetzt oder gelöscht
3
ADC R9, R5
4
ADC R10, R6
5
ADC R11, R7 ; das Output-Carry dieser Operation wird dann meist
Hallo,
der ADC-Befehl addiert einfach die beiden Werte. Wenn aber VOR dem
Befehl das Carry-Flag gesetzt war, wird es auch noch dazuaddiert.
R1 = 0xfe
R2 = 0x03
C = 0
Ergebnis: 0x01, C = 1
R1 = 0xfe
R2 = 0x03
C = 1
Ergebnis: 0x02, C = 1
Oder so:
R1 = 0x01
R2 = 0x02
C = 1
Ergebnis: 0x04, C = 0
ADD ignoriert das Carry-Flag.
R1 = 0xfe
R2 = 0x03
C = 0
Ergebnis: 0x01, C = 1
R1 = 0xfe
R2 = 0x03
C = 1
Ergebnis: 0x01, C = 1
R1 = 0x01
R2 = 0x02
C = 1
Ergebnis: 0x03, C = 0
Gruß
Jonathan
Genau so habe ich es auch verstanden.
Wenn Carryflag anfangs Null bei ADC, dann rechne ich normal, also beide
addieren und wenn es dann nach der Rechnung eine 1 davor steht z.B. f+1,
dann wird Carryflag 1 gesetzt.
Falls Carryflag vor der Rechnung 1 gesetzt ist, wird die 1 dazuaddiert
... also +1 und dann ist das Carryflag nach der Rechnung immer noch
gesetzt, richtig?
Mike schrieb:> und dann ist das Carryflag nach der Rechnung immer noch gesetzt, richtig?
Ja.
Allerdings ist es nicht "immer noch" gesetzt, sondern "schon wieder".
Wegen des neuen Übertrags nämlich.
Hätte noch zwei Fragen: Wie ist das eigentlich beim or Befehl. Habe
einmal 0xa5 und einmal 5a. Beide werden mit or Befehl verarbeitet.
Ergebniss ist dann 0xff, also 255. Carry war vorher gesetzt. Da aber
Wertebereich von 0 bis 255 geht, müsste Carry dann nach dem Ausführen
vom Befehl 0 sein oder? Erst bei 256 müsste Carry =1 sein??!!
Zweite Frage: Stimmt das, dass man nur bei adc und sbc den wertebereich
von -128 bis 127 hat und bei allen anderen Befehlen von 0 bis 255? Die
Frage bezieht sich auf den V-Flag :)
Mike schrieb:> Hätte noch zwei Fragen: Wie ist das eigentlich beim or Befehl. Habe> einmal 0xa5 und einmal 5a. Beide werden mit or Befehl verarbeitet.> Ergebniss ist dann 0xff, also 255. Carry war vorher gesetzt. Da aber> Wertebereich von 0 bis 255 geht, müsste Carry dann nach dem Ausführen> vom Befehl 0 sein oder? Erst bei 256 müsste Carry =1 sein??!!
SChau ins Datenblatt bzw. in die Befehlsbeschriebung deines Prozessors.
Bei jedem Befehl ist akribisch vermerkt, ob und wenn ja welche Flags von
dem Befehl berücksichtigt bzw. verändert werden.
Du wirst diese Information noch oft brauchen und wenn du sie nicht
auswendig weißt dann musst du wissen, wo du sie finden kannst. Im
AVR-Studio ist das besonders einfach: Du stellst den Cursor auf einen
Befehl und drückst F1 (und kannst dann in der Hilfe auch die anderen
Befehle finden)
>> Zweite Frage: Stimmt das, dass man nur bei adc und sbc den wertebereich> von -128 bis 127 hat und bei allen anderen Befehlen von 0 bis 255? Die> Frage bezieht sich auf den V-Flag :)
Nein das stimmt nicht.
Ein Byte ist ein Byte und hat als solches 8 Bit. Ob du diese 8 Bit als
von 0 bis 255 betrachtest (also ohne Vorzeichen) oder als von -128 bis
+127 (also mit Vorzeichen) ist einzig und alleine eine Frage dessen, wie
du die Bitmuster interpretieren willst.
http://www.mikrocontroller.net/articles/AVR-Tutorial:_Arithmetik8
Hi
Sieh dir mal das
http://www.atmel.com/dyn/resources/prod_documents/doc0856.pdf
an.
>Hätte noch zwei Fragen: Wie ist das eigentlich beim or Befehl. Habe>einmal 0xa5 und einmal 5a. Beide werden mit or Befehl verarbeitet.>Ergebniss ist dann 0xff, also 255. Carry war vorher gesetzt. Da aber>Wertebereich von 0 bis 255 geht, müsste Carry dann nach dem Ausführen>vom Befehl 0 sein oder? Erst bei 256 müsste Carry =1 sein??!!
Bei einem 'Oder' kann kein Wert >255 entstehen. In der
Befehlsbeschreibung findest du, wie welche Flags gesetzt werden.
>Zweite Frage: Stimmt das, dass man nur bei adc und sbc den wertebereich>von -128 bis 127 hat und bei allen anderen Befehlen von 0 bis 255? Die>Frage bezieht sich auf den V-Flag :)
Nein. In Assembler gibt es nur Bytes. Daraus kann man Word, DWord ...
machen. Ob du das als vorzeichenbehaftet betrachtest entscheidest du.
Also $FF kann je nach Betrachtungsweise 255 oder -1 sein. Und danach
richtet sich auch die Relevanz der Flags.
MfG Spess
Na gut, aber in der Klausur muss ich entscheiden, ob ich ein Flag setze
oder nicht und soweit ich weiß sind adc und sbc die Befehle, wo ich mich
im Bereich von -127 bis 128 aufhalte und alles was außerhalb ist, ist V
Flag = 1
Der Wertebereich wird nicht durch die Operation bestimmt, die V- oder
C-Flag gesetzt (oder gelöscht) hat, sondern lediglich durch die
Operation, die die Flags dann auswertet (typischerweise ist das ein
bedingter Sprung). Erst an dieser Stelle wird also entschieden, ob
die vorangegangene Rechnung ganzzahlig (Wertebereich 0 .. 255) oder
vorzeichenbehaftet (Wertebereich -128 .. +127) interpretiert werden
soll.
Ok, aber was ich nicht verstehe:
z.B. habe ich eine eor Befehl. Im Instruction Handbuch steht für
Carryflag nach dem Befehl ein "-"
Bedeutet das, dass wenn vorher ein Cflag gesetzt war, es auch nach dem
Befehl gesetzt ist? Es gibt in dem Buch Flags, wo eine Null steht, für
nicht gesetzt, dann gibt es noch diesen Strich "-"
z.B. eor 0xc3, 0xff
Da würde ich kein C-Flag setzen für das Ergebnis. Im Handbuch steht wie
gesagt nur ein Strich "-" ...
Hi
>Da würde ich kein C-Flag setzen für das Ergebnis. Im Handbuch steht wie>gesagt nur ein Strich "-" ...
Es gibt vier Möglichkeiten, wie sich ein Befehl auf ein Flag auswirkt:
- Flag wird entsprechend Ergebnis gesetzt
- Flag wird gelöscht
- Flag wird gesetzt
- Flag bleibt unbeeinflusst
Ein eor ,and , or ... können kein Ergebnis haben, das das Anzeigen
eines Übertrags erfordert. Warum sollte das Flag dann beeinflusst
werden?
MfG Spess
Genau das meinte ich. Wenn in dem handbuch steht z.B. V=0, dann ist V
danach = 0. wenn dort ein rechts/links Pfeil steht, wird Flag vom
Ergebnis beeinflusst. FWenn da aber ein "-" Strich steht, bedeutet das,
dass das Flag genau so bleibt, wie vorher, stimmts?
Weil ganz am einfach jemand geschrieben hat, dass das Flag immer neu
gesetzt wird ... Daher wusste ich nicht genau, was damit gemeint ist. Da
eor das Flag aber wie du schon sagst nicht beeinflusst, wird es, wenn
nicht im handbuch anders beschrieben, nicht Null gesetzt, sondern wie
anfangs angegeben belassen ... Außer es steht im handbuch C=0.
Hab ich das richtig interpretiert?
So nebenbei eine kleine Frage noch. Wenn ich Z=0x0210 habe und z.B. push
zl und push zh schreibe und dann Adresse:Wert sehen möchte, welchen Wert
haben die beiden dann? als Wert habe ich 02 und 10 stehen, aber warum?
Z=0x0210 ist ja nicht mein Wert, sondern damit schaue ich anhand einer
tabelle, welcher Wert darin steckt, ...
Hi
>So nebenbei eine kleine Frage noch. Wenn ich Z=0x0210 habe und z.B. push>zl und push zh schreibe und dann Adresse:Wert sehen möchte, welchen Wert>haben die beiden dann? als Wert habe ich 02 und 10 stehen, aber warum?>Z=0x0210 ist ja nicht mein Wert, sondern damit schaue ich anhand einer>tabelle, welcher Wert darin steckt, ...>...und dann Adresse:Wert sehen möchte, welchen Wert>haben die beiden dann? als Wert habe ich 02 und 10 stehen, aber warum?
Adresse:Wert gibt es nicht. Jeder 'Ladebefehl', der das Z-Register
benutzt, hat auch ein Ziel:
lpm -> r0
lpm rxy,z -> rxy
ld rxy,z -> rxy
das Ziel wird also im Befehl spezifiziert.
MfG Spess
Z ist ein Pointerregister und besteht aus Z= ZH|ZL oder Z=R31|R30
Wenn steht Z=0x0210, dann hat Z auch den Wert 0x0210.
Wenn du aber eine Operation wie
ld R4, Z
oder
st Z, R4
hast, dann beschreibt der Inhalt von Z eine Adresse.