Carry-Flag bei Subtraktion?

OP #2592352
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?
Gast #2592380
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
Gast #2592400
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?
#2592412
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.
Gast #2592426
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.
Gast #2592603
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....
Persönliche Seite #2592617
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.
Gast #2592841
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.
Gast #2592866
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
#2592977
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
#2592994
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
OP #2593205
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.
Gast #2593238
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
OP #2593447
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....
Gast #2593473
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
Persönliche Seite #2593606
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.

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