Forum: Mikrocontroller und Digitale Elektronik Carry-Flag bei Subtraktion?


von Andi Ü. (and0riz0r)


Lesenswert?

Hallo,

ich verstehe, dass ein Rechenwerk ein Carry-Flag ausgibt, wenn bei 
unsigned Additionen ein Übertrag auf das nächste nicht darstellbare Bit 
durchgeführt wird.

Jetzt habe ich gelesen, dass bei einer Subtraktion a-b auch ein 
Carry-Flag gesetzt wird - und zwar dann, wenn der Subtrahend größer als 
der Minuend ist (also b>a).

Wenn ich zum Beipspiel  2 - 3 = -1 rechnen möchte, läuft doch intern 
eine Addition 2 + (-3) ab:

  00000010  (2)
+ 11111101  (-3)
----------
= 11111111   (-1)

Das Rechenwerk würde hier aber kein Carry-Flag setzen. Es findet ja kein 
Übertrag statt.

Woher soll dann das Carry-Flag kommen?
Das einzige was ich mir vorstellen kann ist, das vor der Addition 
automatisch erst eine "Compare"-Operation ausgeführt wird und aufgrund 
deren Ergebniss das Carry-Flag gesetzt wird. Ist das so?

von (prx) A. K. (prx)


Lesenswert?

Andi Ü. schrieb:

> Jetzt habe ich gelesen, dass bei einer Subtraktion a-b auch ein
> Carry-Flag gesetzt wird - und zwar dann, wenn der Subtrahend größer als
> der Minuend ist (also b>a).

Manche Prozessoren setzen C bei a >= b, manche setzen C bei a < b.

von spess53 (Gast)


Lesenswert?

Hi

>Wenn ich zum Beipspiel  2 - 3 = -1 rechnen möchte, läuft doch intern
>eine Addition 2 + (-3) ab:

Eher 2+253=255. Und da entsteht kein Übertrag. Was veranlasst dich zu 
der Annahme, das 0b11111101 vom Controller als -3 angesehen wird? Der 
kennt nur Bytes. Und die gehen von 0..255.

MfG Spess

von Andi (Gast)


Lesenswert?

spess53 schrieb:
> Eher 2+253=255. Und da entsteht kein Übertrag. Was veranlasst dich zu
> der Annahme, das 0b11111101 vom Controller als -3 angesehen wird?

253 entspricht bei signed zahlen -3, genauso wie 255 -1 entspricht. 
Darum kümmert sich letztendlich natürlich der Compiler, aber ich hab es 
halt zur Vereinfachten darstellung mal so hingeschrieben, das man es 
versteht. Grummel. Du


Karl Heinz Buchegger schrieb im Beitrag #2592389:
> Die Subtraktion
>
>   (-70) - 90
>
> wird in 8 Bit unterlaufen, genauso wie
>
>   200 + 60
>
> übergelaufen ist.

Dafür ist doch das Overflow-Bit da. Ich rede von Carry...

A. K. schrieb:
> Manche Prozessoren setzen C bei a >= b, manche setzen C bei a < b.

Ok, das ist hilfreich. Es ist also so, dass bei einer 
Addition/Subtraktion in jedem Fall davor eine Compare Operation 
stattfindet?

von Andi (Gast)


Lesenswert?

spess53 schrieb:
> Und da entsteht kein Übertrag.

hatte ich auch gesagt - les es halt ....

von Xenu (Gast)


Lesenswert?

>Es ist also so, dass bei einer Addition/Subtraktion in jedem Fall davor >eine 
Compare Operation stattfindet?

Nicht davor, sondern gleichzeitig. Addierer und Komparatoren sind 
kombinatorische Logik.

von (prx) A. K. (prx)


Lesenswert?

Andi schrieb:

> Ok, das ist hilfreich. Es ist also so, dass bei einer
> Addition/Subtraktion in jedem Fall davor eine Compare Operation
> stattfindet?

Nein. Aber manche CPUs implementieren die Subtraktion als "Addition des 
Einerkomplements". Und dann führt a>=b zu C=1, a<b zu C=0. Für das 
vorherige C ist das entsprechend, d.h. bei C=1 kriegt man eine 
Subtraktion ohne Übertrag, bei C=0 mit.

Andere CPUs verwenden die echte Subtraktion, bei der das C grad 
andersrum arbeitet.

von (prx) A. K. (prx)


Lesenswert?

Xenu schrieb:

> Nicht davor, sondern gleichzeitig. Addierer und Komparatoren sind
> kombinatorische Logik.

Eine Vergleichsoperation ist technisch gesehen oft identisch mit einer 
Subtraktion, deren Ergebnisdaten verworfen werden, nur die Statusflags 
bleiben.

von Osche R. (Gast)


Lesenswert?

Andi schrieb:

> Ok, das ist hilfreich. Es ist also so, dass bei einer
> Addition/Subtraktion in jedem Fall davor eine Compare Operation
> stattfindet?

Eine Compare-Operation IST eine Subtraktion. Nur dass das Ergebnis 
verworfen wird, d.h. der Operand ändert sich nicht. Compare setzt nur 
die Flags.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andi Ü. schrieb:

> Das Rechenwerk würde hier aber kein Carry-Flag setzen.
> Es findet ja kein Übertrag statt.

Bei der Subtraktion ist's ein Borrow: Ein Borgen von der nächsthöheren 
Stelle.

von Andi (Gast)


Lesenswert?

A. K. schrieb:
> Nein. Aber manche CPUs implementieren die Subtraktion als "Addition des
> Einerkomplements".

Ah, ich dachte, das machen eh alle so. In meinem Beispiel hatte ich das 
deshalb auch so gemacht.
Es gibt offensichtlich keine Pauschal gültige Aussage - mist :)

Johann L. schrieb:
> Bei der Subtraktion ist's ein Borrow: Ein Borgen von der nächsthöheren
> Stelle.

Ja, so nennt man das wohl, aber eine anschauliche "schriftliche 
Subtraktion" nach klassischem Schulrechnen geht nur, wenn b<a ist. 
Insofern kann ich mir ein Borrow nicht so ganz vorstellen....

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andi schrieb:

> Johann L. schrieb:
>> Bei der Subtraktion ist's ein Borrow: Ein Borgen von der nächsthöheren
>> Stelle.
>
> Ja, so nennt man das wohl, aber eine anschauliche "schriftliche
> Subtraktion" nach klassischem Schulrechnen geht nur, wenn b<a ist.

Geht hier genauso:

wenn du 18-9 auf dem Papier rechnest und bei 8-9 eins von links borgst, 
ist das das gleiche wie bei einem 8-Bit Rechner. Nur daß man bei Papier 
und Bleistift als Basis 10 immt und bei einem 8-Bit Rechner eben 256.

Wenn b <= a ist ist wenn irgendwann fertig mit Subtrahieren/Borgen, bei 
b > a sammeln sich aber links immer mehr 9en an, d.h. man bekommt das 
Ergebnis quasi im 10er-Komplement.

von Andi (Gast)


Lesenswert?

sehr amüsant jop, das geht echt ;)

Falls es einen interessiert:

z. B: im Zehnersystem das Beispiel von Johann 18-9 mal anders rum: 9-18 
mit "4 Stellen"

             0009
           - 0018
Übertrag:    110
Ergebnis:  - 9991

Das entsprechende 10er-Komplement ist dann 10000 + (-9991) = 9

Im Binärsystem das Ganze:

            00001001
           -00010010
Übertrag:   1110110
Ergebnis:   11110111

Und das wird natürlich bei 2-er-Komplementbildung wieder
 :)

Ich weiß zwar net genau, was ich jetzt gelernt habe über Carry- und 
Borrow- und Overflow-Flags, aber interessant ises trotzdem :)
Danke an der Stelle.

von spess53 (Gast)


Lesenswert?

Hi

>Ich weiß zwar net genau, was ich jetzt gelernt habe über Carry- und
>Borrow- und Overflow-Flags, aber interessant ises trotzdem :)

Vielleicht, das das nichts mit positiven oder negativen Zahlen zu tun 
hat? Es gibt auch noch andere Flags. Und dem Controller ist es 
vollkommen egal, ob du 0b11111111 als 255 oder -1 interpretierst. 
Deswegen rechnet er nicht anders.

MfG Spess

von (prx) A. K. (prx)


Lesenswert?

Andi schrieb:

>> Nein. Aber manche CPUs implementieren die Subtraktion als "Addition des
>> Einerkomplements".
>
> Ah, ich dachte, das machen eh alle so. In meinem Beispiel hatte ich das
> deshalb auch so gemacht.

Hast du nicht, du hast das Zweierkomplement addiert.

Mit dem Einerkomplement ist es:
  00000010  (2)
+ 11111100  Einerkomplement von 3 (~3)
+        1  C=1 vorher, also kein Subtraktionsübertrag/Borrow
----------
= 11111111  (-1), C=0, also Subtraktionsübertrag/Borrow signalisiert

von Jobst M. (jobstens-de)


Lesenswert?

Beispiel, 16-Bit Subtraktion:

5003 - 421 = 4582 (dez) - Kein negatives Ergebnis!

138B - 01A5 = 11E6 (hex) - auch nicht negativ.

LSB:
  8B
- A5
- 00 <- weil Carry (hoffentlich) nicht gesetzt.
====
  E6 + Carry gesetzt, weil 0 unterschritten

MSB:
  13
- 01
- 01 <- weil Carry gesetzt
====
  11


Gruß

Jobst

von Ralf G. (ralg)


Lesenswert?

Jobst M. schrieb:
> Beispiel, 16-Bit Subtraktion:
>
> 5003 - 421 = 4582 (dez) - Kein negatives Ergebnis!
>
> 138B - 01A5 = 11E6 (hex) - auch nicht negativ.

Okay, dann noch etwas ausführlicher:

16-Bit 'Addition':
5003 + (-421) = 4582 (dez)
138B + FE5B = 11E6 (hex) - mit Übertrag

Das Vorzeichen existiert nur 'in unserer Welt'.

von Jobst M. (jobstens-de)


Lesenswert?

Ralf G. schrieb:
> 138B + FE5B = 11E6 (hex) - mit Übertrag

Bei 8B+5B würde aber gar kein Carry erzeugt, obwohl es benötigt wird.

bei 8B-A5 aber schon

Und

Bei 13+FE wird ein Carry gesetzt,

bei 13-02 aber korrekter weise nicht.

;-)


Gruß

Jobst

von Ralf G. (ralg)


Lesenswert?

Jobst M. schrieb:
> Bei 8B+5B würde aber gar kein Carry erzeugt, obwohl es benötigt wird.

Wird keins erzeugt. Ja. Warum wird da ein Carry benötigt?

von Jobst M. (jobstens-de)


Lesenswert?

Ralf G. schrieb:
> Ja. Warum wird da ein Carry benötigt?

Weil das SUBC ein Borrow (Carry) benötigt um nicht nur 1 von 0x13 
abzuziehen.


Gruß

Jobst

von Andi Ü. (and0riz0r)


Lesenswert?

Nächster Versuch einer allgemeinen Aussage :)

1.
Es gibt Prozessoren die für die Subtraktion:

das Zweierkomplement addieren
das Einerkomplement addieren
wirklich eine Subtraktion durchführen

2.
Signed oder Unsigned kennt ein Prozessor nicht.

3. Jedesmal wenn ein Nulldurchgang des Ergebnisregisters stattfindet, 
wird ein Carry/Borrow-Flag gesetzt.

4. Jedesmal wenn das MSB sein Vorzeichen wechselt, wird das 
Overflow-Flag gesetzt. Aber nur, wenn KEIN Carry-Flag gesetzt ist.

von spess53 (Gast)


Lesenswert?

Hi

>3. Jedesmal wenn das MSB sein Vorzeichen wechselt, wird das
>Overflow-Flag gesetzt. Wie das weiterverarbeitet wird ist dem Prozessor
>egal. Bei unsigned wird es ignoriert, bei signed wird es berücksichtigt,
>wenn die MSB der Operanden gleich sind.

Nein.

 0b11111111
+0b11111111
-----------
 0b11111110  -> kein 'Vorzeichenwechsel' trotzdem 'Overflow'-> Cy=1

Außerdem wird das N-Flag (Negative) gesetzt weil beim Ergebnis Bit7 
gesetzt ist.

>4. Jedesmal wenn ein Nulldurchgang eines Registers stattfindet wird ein
>Carry/Borrow-Flag gesetzt.

Z.B. haben AVRs weder ein Overflow- noch ein Borrow-Flag. Beides wird 
über das Carry-Flag geregelt.

Für vorzeichenbehaftete Zahlen gibt es noch eigene Flags:

N : Negative flag in status register
V : Two's complement overflow indicator
S : N [+] V, For signed tests

MfG Spess

von (prx) A. K. (prx)


Lesenswert?

spess53 schrieb:

> Z.B. haben AVRs weder ein Overflow- noch ein Borrow-Flag. Beides wird
> über das Carry-Flag geregelt.

Overflow lässt sich nicht über Carry abwickeln. Das gibts bei AVRs sehr 
wohl. Intels 8080 und 8051 haben keines.

von Andi Ü. (and0riz0r)


Lesenswert?

spess53 schrieb:
>>3. Jedesmal wenn das MSB sein Vorzeichen wechselt, wird das
>>Overflow-Flag gesetzt. Wie das weiterverarbeitet wird ist dem Prozessor
>>egal. Bei unsigned wird es ignoriert, bei signed wird es berücksichtigt,
>>wenn die MSB der Operanden gleich sind.
>
> Nein.

Ok, dann eben anstatt von "Vorzeichenwechsel" vielleicht "wenn ein 
Übertrag auf das MSB stattfindet"?

spess53 schrieb:
> V : Two's complement overflow indicator

genau das ist doch beim AVR das Overflowflag....

von spess53 (Gast)


Lesenswert?

Hi

>Overflow lässt sich nicht über Carry abwickeln. Das gibts bei AVRs sehr
>wohl. Intels 8080 und 8051 haben keines.

'Overflow' ist ein sehr dehnbarer Begriff. Eigentlich ist es einfach nur 
die Überschreitung des Wertebereichs z.B. eines Bytes. Deshalb sollte 
man es hier schon spezifizieren, so wie es ATMEL mit 'Two's complement 
overflow' macht.

MfG Spess

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Andi schrieb:
> sehr amüsant jop, das geht echt ;)
>
> Falls es einen interessiert:
>
> z. B: im Zehnersystem das Beispiel von Johann 18-9 mal anders rum: 9-18
> mit "4 Stellen"
>
>              0009
>            - 0018
> Übertrag:    110
> Ergebnis:  - 9991
>
> Das entsprechende 10er-Komplement ist dann 10000 + (-9991) = 9

Nicht ganz. Das Ergebnis ist nicht -9991 sondern 9991 bei Verwendung 
von 4 Stellen. Analog zum 2-er Komplement sind dann alle Zahlen x >= 
5000 als negative zu interpretieren als x-10000.

Oben ist das Ergebnis natürlich 9991-10000 = -9 und nicht wie 
geschrieben 9.

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.