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 |
6 | ; ignoriert |
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.
Also hat es nichts damit zutun, wie die Falgs vor der Operation gesetzt waren und es hat auch nichts direkt mit dem Befehl zutun?
Mal so zur bildlichen Darstellung: (111 = jeweils 1 gemerkt: Das ist ein Flag (hier von 1 bis 9, binär nur 1) 789 + 456 ---- 1245
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
Das "-" bedeutet: Das jeweilige Flag wird durch diese Operation nicht beeinflusst.
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.
Also bei mir steht z.B. Z=0x0210 und mein ZH ist 0x02 und ZL ist 0x10 .... steht zumindest so ...
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.