Overflow Bit bei Addition

Gast #1080374
Lesenswert?

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
#1080383
Lesenswert?

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.
Gast #1080391
Lesenswert?

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 ;-)
#1080397
Lesenswert?

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?
Gast #1080405
Lesenswert?

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
#1080415
Lesenswert?

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
Gast #1080419
Lesenswert?

>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.
#1080440
Lesenswert?

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 )...
#1080448
Lesenswert?

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.
Gast #1080465
Lesenswert?

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.
Gast #1080472
Lesenswert?

>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.
Gast #1080583
Lesenswert?

>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
Angehängte Dateien:

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren