Hi, ich habe nun schon eine halbe Stunde hier im Forum gesucht, ob diese Frage nicht schon irgendwo beantwortet wurde, aber leider nichts gefunden, da das Niveau dieses Forums anscheinend etwas höher anzusiedeln ist. Also, ich bin Mechatronikstudent und habe nun für die Klausur noch folgendes Problem, was ich durch meine bisherigen Recherchen nicht lösen konnte. Ausgangslage (rein theoretisch): Mikrocontroller: AtMega8 Rechenoperation: Addition zweier Zahlen Wertebereich: 0 bis 255 Wenn ich nun 89 zu 170 addiere, dann überschreite ich den Wertebereich und das Carry Bit wird gesetzt. Das Ergbnis ist also 3 und das C-Bit ist gesetzt. Wenn ich nun allerdings 170 zu 89 addiere, wird dann neben dem Carry-Bit auch das Overflow-Bit gesetzt? Unser Dozent hat uns erklärt, dass das Overflow-Bit in diesem Wertebereich beim Übergang von 127 zu 128 gesetzt wird. Wenn das so stimmt dann würde das Kommutativgesetz für diese Rechenoperation im Mikrocontroller nicht gelten, weil 89 + 170 ein anderes Ergebnis (zusätzlich das Overflow-Bit gesetzt) liefern würde als 170 + 89. Wäre für eine Erklärung sehr dankbar, bitte versuchen die Erklärung möglichst unkompliziert zu gestalten. vlg Johannes W
Das Overflow Flag wird nur dann ausgewertet, wenn mit vorzeichenbehafteten Zahlen (Zweierkomplement!) gerechnet wird. Der Wechsel von 0x7F nach 0x80 ist in dem Falle nämlich nicht der Überlauf von 127 zu 128, sondern von 127 zu minus 128. Wenn Du mal in die Dokumentation geschaut hättest, dann hättest Du auch gesehen, dass das Flag dort explizit als "two's complement overflow" bezeichnet wird... Und ja, das Overflow Flag wird in dem Fall immer gesetzt, da der Controller ja zum Zeitpunkt der Rechenoperation noch nicht weiß, ob das Ergebnis als vorzeichenbehaftet oder vorzeichenlos interpretiert werden soll. Schließlich steht das erst bei der folgenden Verzweigungsoperation fest.
aber woher weiß der mikrocontroller ob es sich um eine Rechnung mit Zweierkomplement handelt oder nicht? dachte unser Dozent hätte uns erzählt, dass der Mikrocontroller da nicht unterscheiden kann und es alleine durch Interpretation des Programmierers zu einer negativen Zahl wird. AVR Studio Simulator besitze ich nicht ;-)
Johannes W wrote: > aber woher weiß der mikrocontroller ob es sich um eine Rechnung mit > Zweierkomplement handelt oder nicht? Gar nicht! Der µC rechnet nur ganz stur mit Bits. Wie die Zahlen letztendlich interpretiert werden, kann dem µC auch völlig egal sein, weil es für ihn keinen Unterschied macht. Er teilt nur dem "Benutzer" mit, wenn ein Überlauf in das MSB (oder aus dem MSB) stattgefunden hat, weil das bei einer Zweierkomplement-Darstellung (bei der das MSB das Vorzeichenbit ist) einen Überlauf vom höchsten zum niedrigsten darstellbaren Wert oder umgekehrt stattgefunden hat. > dachte unser Dozent hätte uns erzählt, dass der Mikrocontroller da nicht > unterscheiden kann und es alleine durch Interpretation des > Programmierers zu einer negativen Zahl wird. Genau, so ist es auch. Warum hast Du Probleme, daran zu glauben?
ok, glaube du hast mein problem damit gelöst. :-) ich habe es jetzt so verstanden: Overflow Flag wird immer gesetzt von Übergang 127 --> 128/-128 Interpretiert wird es allerdings nur wenn der Anwender mit Zweierkomplement rechnen wollte, ansonsten wird das Flag wieder gelöscht. Wenn das so richtig ist, bitte kurze Bestätigung, und dann kann der Thread geschlossen werden, bin wunschlos glücklich. Vielen Dank
Die Atmel-Dokumentation zum Additions-Opcode ADD sagt, wie das Overflow-Bit V behandelt wird: "V: Rd7•Rr7•R7+Rd7•Rr7•R7 Set if two’s complement overflow resulted from the operation; cleared otherwise." Hierbei sind Rd7 und Rr7 jeweils das Bit 7 (MSB, manchmal Vorzeichenbit) der beiden Operanden, R7 ist das MSB des Ergebnisses. Wenn Du das mit Deinen beiden Additionen durchführst, dann wirst Du feststellen, daß in beiden Fällen derselbe Wert für den Overflow herauskommt. Noch eines: Der Overflow ist bei unsigned Operationen vollkommen bedeutungslos; er spielt ausschließlich bei signed Operationen eine Rolle. Im übrigen ist bei allen Gesetzen der Mathematik sehr genau zu prüfen, ob sie auch dann gelten, wenn die Zahlendarstellung - wie üblicherweise im Computer - kein Zahlenstrahl_ sondern ein _Zahlenkreis ist. Hier gilt z. B. bereits nicht mehr, daß N + 1 > N ist. Genauso gibt es nur eine endliche Anzahl Gleitkommazahlen, bedingt durch die endliche Breite der Zahlendarstellung. Bernhard
>Interpretiert wird es allerdings nur wenn der Anwender mit >Zweierkomplement rechnen wollte, ansonsten wird das Flag wieder >gelöscht. Nein, so kann man das nicht sagen. Es wird nicht "wieder gelöscht", sondern das Flag wird gesetzt, und der Anwender entscheidet, ob er es beachten will, indem er z. B. danach einen Verzweigungsbefehl "springe wenn V-Flag = 0" schreibt, oder "springe wenn V-Flag = 1" oder irgendeinen anderen, der das V-Flag als Bedingung hat.
>AVR Studio Simulator besitze ich nicht ;-)
Den kannst du dir doch kostenlos von der Atmel Seite runterladen
Gruss Helmi
Zusatz: Schreibt er dagegen einen Verzweigungsbefehl "springe wenn C-Flag = 0" oder "springe wenn Z-Flag = 1", dann wird das V-Flag auch gesetzt, aber es bleibt ohne Auswirkung.
Johannes W wrote: > ok, glaube du hast mein problem damit gelöst. :-) > > ich habe es jetzt so verstanden: > Overflow Flag wird immer gesetzt von Übergang 127 --> 128/-128 Ja. Aber es ist besser, sich das in Hexadezimal oder Binär zu veranschaulichen als Änderung des MSB. > Interpretiert wird es allerdings nur wenn der Anwender mit > Zweierkomplement rechnen wollte, ansonsten wird das Flag wieder > gelöscht. Nein, das Flag wird erst dann wieder geändert, wenn der nächste Befehl, der Einfluss darauf hat, es ändert. Der Benutzer hat normalerweise an den Statusflags überhaupt nicht zu schrauben, also auch nicht zu löschen. Die Flags werden auschließlich von der ALU geändert (einzige Ausnahme natürlich das I-Flag, das sowieso eine ganz andere Aufgabe hat). Aus dem Programm heraus wird i.d.R. nur lesend zugegriffen, z.B. über einen Branch-Befehl. Und wenn Du Dir in der Befehlsdokumentation mal die Beschreibung dieser Befehle anschaust, dann wirst Du auch verstehen, wie es läuft. V.a. dann, wenn Du feststellst, dass die ganzen brXX-Befehle nur andere Schreibweisen für brbs bzw. brbc sind und jeweils ein ganz bestimmtes Flag auswerten. Schau Dir z.B. mal speziell brlo und brlt an (oder brsh und brge )...
Johannes W wrote: > Wenn ich nun allerdings 170 zu 89 addiere, wird dann neben dem Carry-Bit > auch das Overflow-Bit gesetzt? Nein. Bei der Addition gilt das Kommutativgesetz, d.h. die Operanden sind vertauschbar. Es kann also nicht beim Vertauschen was anderes rauskommen. Ein Überlauf bei vorzeichenbehaftet betrachteten Zahlen kann nur dann auftreten, wenn beide Operanden negativ oder beide positiv sind und ein Vorzeichenwechsel (Bit 7 kippt) erfolgt. 170 entspricht vorzeichenbehaftet der -86, ist also negativ. Daher wird das Überlaufbit in beiden Fällen gelöscht. Peter P.S.: Ich behaupte mal, Carry und Überlauf schließen sich bei der Addition gegenseitig aus. Es kann nur eines von beiden gesetzt sein.
ok, wunderbar, habe mir alle Verbesserungen und Erklärungen durchgelesen, und manche davon haben wir bei meinem Gesamtverständnis noch weitergeholfen. Aber ihr müsst verstehen dass ich mir das Zeug nicht zur Lebensaufgabe mache sondern nur eine Klausur bestehen möchte. Meine Frage ist für meinen Horizont hinreichend genau beantwortet worden, also bitte bemüht euch nicht weiter um immer exaktere Erklärungen. Da mein Dozent es selber nicht wusste nehme ich auch nicht an dass er in der Klausur tiefer darauf eingehen wird. Jedenfalls allen die mir Erklärungen und Verbesserungen geschrieben haben vielen Dank und noch einen schönen Abend.
>Ich behaupte mal, Carry und Überlauf schließen sich bei der Addition >gegenseitig aus. Es kann nur eines von beiden gesetzt sein. Fast richtig. Von den 65536 möglichen Kombinationen für "add a, b" führt eine einzige (!) zu gesetztem Carry und Overflow, nämlich a = 128 und b = 128. In diesem Fall wird Z = C = S = V = 1 und N = 0.
hast du alle einzeln durchprobiert bis du auf das ergebnis gekommen bist? :D :D :D :D :D
Stimmt, die -128 ist ne böse Zahl, selbst ihr Betrag ist negativ. Peter
>hast du alle einzeln durchprobiert bis du auf das ergebnis gekommen bist?
Nein, aber ich hätte es besser tun sollen. Dann hätte ich meinen Fehler
gemerkt. Es gibt noch mehr Fälle, bei denen C und V gesetzt werden. In
dem Bild (Anhang) sind alle V=1-Fälle gelb getönt, und alle, bei denen
C=1 wird, rot umrandet. C und V werden also gleichzeitig gesetzt für
alle durch das RECHTE UNTERE GELBE FELD repräsentierten Fälle. Dazu
gehört a = b = 128, aber auch z. B. a = b = 150 (bis a = b = 191), oder
a = 253, b = 130.
Insgesamt sind es genau 8256 Fälle, nicht nur einer.
Ein Programm, das diese Zahl automatisch berechnet, benötigt nur wenige
Instruktionen:
1 | clr ZL |
2 | clr ZH |
3 | |
4 | clr a |
5 | clr b |
6 | |
7 | Loop: |
8 | mov t, a |
9 | add t, b |
10 | |
11 | brcc Continue |
12 | brvc Continue |
13 | |
14 | ; success: C=1 and V=1! |
15 | adiw ZL, 1 |
16 | |
17 | Continue: |
18 | dec b |
19 | brne Loop |
20 | |
21 | dec a |
22 | brne Loop |
23 | |
24 | End: |
25 | ; ZL:ZH hat jetzt den Wert 8256 |
@Gast (Gast) Schönes Bildchen. Da sieht man auch gut, daß das Kommutativgesetz gilt. Ist natürlich klar, daß beim Überlauf zweier negativer Werte auch immer das Carry gesetzt ist und beim Überlauf zweier positiver Werte nie. Peter
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.