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?
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.
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
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?
>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.
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.
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.
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.
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.
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....
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.
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.
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
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
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
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'.
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
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?
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
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.
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
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.
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....
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
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.