Overflow-und Carry-flags auf Z80
Habe ich so Runde um die Umsetzung der ADD A,r Satz von opcodes, die auf meinem Z80 Kern. Ich hatte ein wenig Verwirrung über das carry-und overflow-flags, die ich glaube, ich habe genagelt, aber ich wollte es der community, um zu überprüfen, dass ich im Recht bin.
Grundsätzlich von dem, was ich sehen kann, ist die ALU in der Z80 kümmert sich nicht darum, signed/unsigned-Operationen, es fügt nur bits. Dies bedeutet, dass, wenn zwei 8-bit-Werte addiert und zu einem 9-bit-Wert als Ergebnis Ihrer addition das carry-flag gesetzt wird. Dieser Zusatz enthält zwei negative zweier-Komplement-zahlen von beispielsweise -20 (11101100) und -40 (11011000), denn obwohl das Ergebnis -60 (11000100), das Ergebnis ist eigentlich ein 9-bit-Wert 1 1100 0100. Diese sicherlich bedeutet, wenn das hinzufügen zwei negative Zweierkomplement Werte, das carry-flag wird immer gesetzt, auch wenn es keine überlauf - habe ich Recht?
Zweitens, habe ich beschlossen, dass zur Erkennung von überlauf in dieser Anleitung, würde ich XOR bit 7 der beiden Operanden, und wenn das Ergebnis war 10000000, dann ist es auf jeden Fall keine überlauf - wenn das Ergebnis dies ist 00000000 dann könnte es ein überlauf, da die Anzeichen sind die gleichen, und daher würde ich XOR bit 7 des Ergebnisses der addition mit bit 7 von entweder operand ist, und wenn das Ergebnis ist 10000000 dann ein überlauf aufgetreten ist und ich die P/V overflow-flag. Bin ich hier richtig auch?
Sorry für so eine verwickelte Frage, ich bin mir ziemlich sicher, dass ich Recht habe, aber muss ich wissen, bevor ich auf unzählige weitere Anweisungen basierend auf dieser Logik. Vielen Dank.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die bits des Ergebnisses sind, die aus der abgeschnitten Summe der vorzeichenlosen Ganzzahlen. Der add-Befehl kümmert sich nicht um die hier Unterschreiben, noch macht Sie sich über Ihre eigene interpretation der Integer als signed oder unsigned. Es fügt nur wie, wenn die zahlen ohne Vorzeichen.
Das carry-flag (oder borgen bei der Subtraktion) ist, dass nicht-existent 9. bit aus der addition der 8-bit unsigned Integer. Effektiv, dieses flag signalisiert einen überlauf/Unterlauf bei add/sub unsigned Integer. Wieder, fügen Sie kümmert sich nicht um die Zeichen, die hier überhaupt, es fügt nur wie, wenn die zahlen ohne Vorzeichen.
Hinzufügen von zwei negativen 2-Komplement-zahlen wird das Ergebnis in die Festsetzung des carry-flag auf 1, richtig.
Das overflow-flag zeigt an, ob oder nicht es wurde ein überlauf/Unterlauf bei add/sub-Ganzzahlen mit Vorzeichen. Um die überlauf-flag die Anleitung behandelt die Zahl als signed (genau wie es behandelt diese als unsigned für das carry-flag und der 8 bit des Ergebnisses).
Die Idee, die hinter der Einstellung der overflow-flag ist einfach. Angenommen, Sie melden Sie-erweitern Sie Ihre 8-bit-Ganzzahlen mit Vorzeichen zu 9 bits, das wird, kopieren Sie einfach das 7. bit in eine extra, 8. bit. Ein überlauf/Unterlauf tritt auf, wenn die 9-bit-Summe/Differenz dieser 9-bit-Ganzzahlen mit Vorzeichen hat unterschiedliche Werte in den bits 7 und 8, was bedeutet, dass die addition/Subtraktion verloren hat, das Ergebnis ist Zeichen im 7-bit und verwendet es für das Ergebnis der Größe ist, oder, in anderen Worten, die 8 bits können nicht genügend Platz für das Vorzeichen-bit und einem so großen Ausmaß.
Nun, bit 7 des Ergebnisses kann sich von der imaginären Zeichen bit 8 wenn und nur wenn das carry in bit 7 und die tragen in 8 bit (=carry out bit 7) unterschiedlich sind. Das ist, weil wir beginnen mit dem Summanden mit bit-7=bit-8 und nur unterschiedliche carry-ins, Sie können Sie beeinflussen in der Folge unterschiedliche Wege.
Also overflow-flag = carry-out-flag XOR von bit 6 ins bit 7.
Beide, meine und Ihre Wege zur Berechnung der überlauf-flag korrekt sind. In der Tat, beide sind beschrieben in der Z80-CPU Benutzerhandbuch im Abschnitt "Z80-Status-Anzeige-Flags".
Hier ist, wie können Sie emulieren die meisten ADC-Anweisung in C, wo Sie keinen direkten Zugriff auf CPU-flags und kann nicht nehmen Sie vollen Vorteil der Emulation der CPU ' s ADC Befehl:
Ausgabe:
Können Sie ändern
#if 0
zu#if 1
verwenden die Zeichen-Vergleich basierende Methode für überlauf Berechnung. Das Ergebnis wird das gleiche sein. Auf den ersten Blick ist es etwas überraschend, dass die sign-based-Methode kümmert sich um das carry-in zu.Bitte beachten Sie, dass durch meine Methode, welche ich zur Berechnung aller carry-ins, die in bits 0 bis 7 erhalten Sie auch gratis den Wert der
half-carry
- flag (carry von bit 3 auf bit 4), die nötig ist, damit dieDAA
Unterricht.EDIT: ich habe eine Funktion für die Subtraktion mit borrow (SBC/SBB-Anweisung) und die Ergebnisse für Sie.
halfCarryOut = carryIn ? ((a & 0x0F) >= 0x0F - (a & 0x0F)) : ((a & 0x0F) > 0x0F - (a & 0x0F)); halfCarryOut = ((res ^ a ^ b) >> 4) ^ halfCarryOut;
ist, sollte es korrigieren.carryIns = *acc ^ a ^ b;
tunhalfCarryOut = (carryIns >> 4) & 1;
, das ist alles, was Sie brauchen, um hinzuzufügen.Anderen Weg, um zu sehen diese, die ist vielleicht einfacher zu verstehen. Bei der Durchführung einer Summe:
N
bekommt explizit nur set, wenn die Letzte operation war eine Subtraktion. (Ich denke, dies ist für dieDAA
instruction nur.)