Warum ist das Carry-Flag bei einer Subtraktion bei null ist der minuend?
Im moment Schreibe ich meine eigene kleine Bibliothek für arithmetische und logische Operationen für sehr große vorzeichenlose Ganzzahlen. Um die performance zu verbessern habe ich beschlossen, einige Funktionen in der Montage. So, hier ist meine Frage.
Während die Subtraktion von zwei vorzeichenlosen ganzen zahlen das Carry-Flag ist gesetzt, wenn ich eine beliebige Zahl abziehen, von 0.
Aber warum ist das Carry-Flag in dieser situation? Das Carry-Flag ist nur gesetzt, wenn ein überlauf Auftritt, aber wenn ich eine beliebige Zahl abziehen von der null verstehe ich nicht, einen überlauf.
Oder bin ich falsch?
- Hinweis: schreiben Sie Ihre eigenen Operationen in der Montage-möglicherweise nicht die Optimierung, die Sie erwarten. Der compiler überprüft nicht die inline-Montage und hat keine Möglichkeit zu optimieren. Finden Sie die compiler besser optimieren, wenn du einfach eine logische C-code.
- Vielen Dank für Ihre Beratung. Aber ich weiß nicht inline-assembler. Ich Schreibe separate Teile in der Montage und ich einen link auf diese Objekt-Dateien mit dem C-code.
- Dann gibt es noch weniger chance, es kann eine beliebige Optimierung des assembler-Routinen innerhalb der gesamten Struktur des Codes. Versteh mich nicht falsch, ich bin nicht klopfen versuchen, um an Geschwindigkeit zu gewinnen mit assembler, ich dachte es würden immer schneller zu, aber vergleichen Sie immer die Leistung des Codes mit verknüpften Montage auf die Leistung des Codes geschrieben in gerade C mit vollständiger compiler Optimierungen (
-O3
auf den meisten-Ofast
für die gcc-version >= 4.6.0). Compiler Recht gut optimieren heute und 9/10-mal die geraden C wird schneller sein. - OK, danke ich werde das im Hinterkopf behalten. Das größte problem, das ich habe, ist die Tatsache, dass es keinen einfachen Weg, in C überprüfen Sie den status des carry-flag und verwenden Sie es im weiteren Betrieb. Also im moment nutze ich das höchstwertige bit des vorzeichenlosen integer-Typ, wie das carry-flag. Aber ich bin nicht wirklich zufrieden mit, dass. Das ist, warum ich umsetzen will, die core-Logik der Subtraktion und addition in assembler. Aber vielleicht hat ja jemand eine bessere Idee, das zu tun. Ich bin immer offen für andere Vorschläge.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Carry-flag ist tragen oder leihen Sie sich aus dem höchstwertigen bit (MSb):
Nicht zuordnen, die CF mit dem Vorzeichen-bit, in eine Subtraktion CF wird gesetzt, wenn der minuend, so behandelt, als vorzeichenloses kleiner als der subtrahend, so behandelt, als unsigned.
Dies entspricht einem überlauf, für vorzeichenbehaftete zahlen, die äquivalente flag wird VON.
Für eine (unnötige?) visuellen Hinweis, in diese 4-5-Betrieb, es ist die zweite leihen, die rote, die das CF -
Nicht, wenn Sie subtrahieren von null, es kommt natürlich, dass für eine beliebige Anzahl, aber null selbst, Sie haben immer das CF gesetzt ist, als der subtrahend hat mindestens ein bit gesetzt ist.
Schließlich, einige Anweisungen können Sie das Vorzeichen-bit, ohne die CF (siehe zum Beispiel die Logik-Operationen oder das Verhalten von
neg
).neg
hat Effekt das carry-flag aber.Wir wissen aus der Grundschule, dass a - b = a + (-b). Und das ist, wie Logik funktioniert es nicht wir subtrahieren wir die negative. Wir wissen auch von Anfänger Programmierung-Klassen, die mit zweit ergänzen, um die negative invertieren Sie und fügen Sie ein. a - b = a + (~b) + 1. Wir wissen auch aus der Grundschule, das Konzept zu tragen. 9+3 = 2 tragen die eine. Gleich in eine Binärzahl mit zwei Operanden, die Sie haben können, 1 + 1 = 0, tragen die ein. Also jede Spalte in der Logik braucht ein tragen. Es sind jeweils drei bits in zwei bits aus, die zwei Operanden in plus carry in und carry out und das Ergebnis aus. Da jeder dieser Logik blobs hat ein input-bit, carry-in, normalen neben, die ersten tragen ist eine null, aber für die Subtraktion, die wir machen können, dass carry-in 1 und invertieren der zweite operand zu erhalten a + b = a + (~b) + 1
Also die Subtraktion entspricht einer addition, wenn Sie durch ein paar einfache Beispiele, oder besser versuchen, alle drei bit-Kombination von Operanden selbst. Sie werden sehen, dass es keine solche Sache als signed noch unsigned addition (oder Subtraktion), die Schönheit der zweier-Komplement-Codierung.
Wissen, alle diese, Subtraktion, addition, mit außerdem erhalten wir die Durchführung auf UNSIGNED überlauf der signed overflow-bit ist, wenn das carry-in und carry-out des msbit nicht passen, in der Regel vertreten, wie das V-flag. Nun einige Architekturen, da Sie bereits die Invertierung der b-operand auf dem Weg in und carry-in auf den Weg, Sie invertiert das carry-out auf dem Weg nach draußen. EINIGE NICHT. Also Sie haben zu prüfen, Ihre Besondere Architektur zu verstehen, wenn das carry-out ist als eine vorzeichenlose addition-überlauf oder ein borrow. oder nicht leihen oder was auch immer.
null minus etwas nicht immer gehen, um eine Durchführung für die Ergänzung.
Die Durchführung der addition ist null. Ihre Architektur kann wählen, um es so lassen oder Sie können wählen, invertiert es und nennen es eine ausleihen.
Innerhalb einer Architektur-Familie. Alle x86s oder alle der Arme ist es wahrscheinlich, dass Sie werden fortfahren, es zu tun die gleiche Weise für immer. Aber es gibt keinen Grund zu erwarten, dass ARM-und MIPS-und x86-und XYZ-alle tun es auf die gleiche Weise.
Invertierenden und definieren es als ein leihen macht Sinn, von einem Terminologie-Perspektive.
Beachten Sie, dass alle (signed/unsigned) größer als, kleiner als, größer als oder gleich, kleiner als oder gleich " - Definitionen sind auf der Grundlage der carry/borrow Wahl für die Architektur, Sie kann nicht übersetzen diese Flagge Vergleiche über Architekturen, es sei denn, Sie haben die gleiche definition.