Forum: Mikrocontroller und Digitale Elektronik Overflow Bit bei Addition


Announcement: there is an English version of this forum on EmbDev.net. Posts you create there will be displayed on Mikrocontroller.net and EmbDev.net.
von Johannes W (Gast)


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

von Johannes M. (johnny-m)


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.

von neeeee (Gast)


Lesenswert?

Was spricht dagegen, das auf dem AVR Studio simulator zu probierewn ?

von Johannes W (Gast)


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 ;-)

von Johannes M. (johnny-m)


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?

von Johannes W (Gast)


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

von neeeee (Gast)


Lesenswert?

AVR Studio kann man bei Atmel gratis runterladen und beinhaltet den 
simulator

von Bernhard R. (barnyhh)


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

von Gast (Gast)


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.

von Helmut L. (helmi1)


Lesenswert?

>AVR Studio Simulator besitze ich nicht ;-)

Den kannst du dir doch kostenlos von der Atmel Seite runterladen

Gruss Helmi

von Gast (Gast)


Lesenswert?

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.

von Johannes M. (johnny-m)


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 )...

von Peter D. (peda)


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.

von Johannes W (Gast)


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.

von Gast (Gast)


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.

von Johannes W (Gast)


Lesenswert?

hast du alle einzeln durchprobiert bis du auf das ergebnis gekommen 
bist?
:D :D :D :D :D

von Peter D. (peda)


Lesenswert?

Stimmt, die -128 ist ne böse Zahl, selbst ihr Betrag ist negativ.


Peter

von Gast (Gast)


Angehängte Dateien:

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

von Peter D. (peda)


Lesenswert?

@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
Noch kein Account? Hier anmelden.