2011-01-10 17 views
4

Ich bin mehr als auf halbem Weg durch das Lernen Assembly und ich bin vertraut mit dem Konzept, wie vorzeichenbehaftete und unsigned Ganzzahlen in Bits präsentiert werden, ich weiß, dass es eine seltsame Frage scheinen mag, von welcher die Antwort ziemlich offensichtlich wäre, aber Ich frage mich, ob eine arithmetische Operation wie Addition für ein Zahlenpaar sinnvoll ist, von denen einer als signiert und der andere als nicht signiert gilt. Ich habe an mehrere Beispiele gedacht, die ein korrektes Ergebnis liefern:würde arithmetische Operation auf ein Paar von vorzeichenbehafteten und vorzeichenlosen Zahlen legal sein?

10000001 (1-Byte-Ganzzahl ohne Vorzeichen und betrachtet, äquivalent zu 129)
+
11111111 (1-Byte-Ganzzahl und signiert betrachtet (zweier-Komplement-System), das entspricht -1)


10000000 (1-Byte-Ganzzahl und in unsigned Logik äquivalent zu 128)

Nun, wenn der obere Wert war in AL registrieren und wir hatten die folgenden Befehlscode (in GAS-Format):

addb -1, %al 

dann wird das Übertragsflag (CF) des EFLAGS-Registers gesetzt, nachdem die Operation ausgeführt wurde und würde über einen Überlauf informieren, der tatsächlich nicht stattgefunden hat, und vielleicht weil es eine vorzeichenlose Zahl bezüglich eines Überlaufs des Überlaufflags (OF) von gibt EFLAGS-Register sollte referenziert werden. Ich bin also verwirrt, wenn es so ist, dass es so vernünftig ist.

Antwort

1

fand ich dieses sehr schöne article auf das Problem, das mein Hauptanliegen und die Antwort war nach dem Lesen der Artikel klar.

3

Ob eine Zahl oder Operation signiert oder unsigniert ist, ist nur eine Frage der Interpretation. Was passiert, wenn Sie das Addieren machen, ist, dass diese zwei Zahlen addiert werden, um 10000000 mit einem 1 im Übertragsflag zu machen (weil es "vom Frontend ging"). Es liegt dann an Ihren nachfolgenden Operationen zu interpretieren, was das bedeutet (wenn Sie das Bit woanders verwenden, ist es so, als würden Sie den Vorgang als unsigniertes Add ohne Wrapping behandeln; wenn Sie das Bit wegwerfen, ist es so, als würden Sie ein Signed machen hinzufügen).

+0

Das ist nur wahr, wenn das Ergebnis die gleiche Größe wie alle Operanden hat. Prozessoren haben häufig Multiplikationsanweisungen, deren Ergebnisgröße das Doppelte der Operandengröße ist. Einige haben auch Additionsanweisungen, bei denen Operanden unterschiedlich groß sind (zB ADD.W D3, A5 auf dem 68000 oder 'ADD * +' auf dem TMS32050 werden einen 16-Bit-Wert vorzeichenerweitern und zu einer 32 hinzufügen -BIT-Register Das TMS hat auch ADDU * + ', um einem 32-Bit-Register einen vorzeichenlosen 16-Bit-Wert hinzuzufügen – supercat

3

Bei binärer Ebene gibt es nur eine Addition:

0101 + (5) 
1010 = (unsigned 10 or signed -6) 
-------- 
1111 (unsigned 15 or signed -1) 

Was ist mit dem Übertrag und Überlauf-Flags, werden sie beide setzen auf einfache Regeln entsprechend. CF kann verwendet werden, um einen Überlauf zu erkennen Wenn Wir betrachten, dass die Operanden unsigned waren, und OF, um den Überlauf zu erkennen Wenn Wir betrachten beide von ihnen signiert. Diese beiden Flags werden entsprechend dem Ergebnis gesetzt, und es liegt an Ihnen zu entscheiden, welche von ihnen zu verwenden ist.

Die tatsächliche Formel für OF-Flag

OF = CF xor MSB_of_result. 

Das bedeutet, dass, wenn wir das Hinzufügen von zwei positiven Zahlen (die wir unterzeichnet beachten), dann, wenn das Ergebnis negativ ist, dann ist es oveflowed.

1

"Signed" und "unsigned" sind Interpretationen. Bei einer Montageanweisung wird die Interpretation im Allgemeinen dokumentiert. Ich kenne keine Architektur, in der es eine ADD-SIGNED-UNSIGNED-Anweisung gibt, die eines ihrer Argumente als vorzeichenbehafteten Wert und eines als vorzeichenlos interpretiert. Es scheint auch wenig Wert darin zu haben. Bei 2s-Komplement-Ganzzahlarithmetik würde der einzige Unterschied in einigen Flagregistern bestehen.

+0

Es ist zwar nicht üblich, dass Prozessoren Multiplikationsbefehle im gemischten Modus, Multiplikation von vorzeichenbehafteten Werten mit erweiterter Genauigkeit, anbieten erfordert solche Operationen, ob sie mit dedizierten Anweisungen oder Codesequenzen implementiert sind – supercat

6

Mathematisch fügen Sie keine Zahl mit Vorzeichen oder Vorzeichen hinzu. Es gibt nur Werte modulo 2 (vorausgesetzt, Sie haben 32-Bit-Register).Solche Werte decken einen Bereich von aufeinanderfolgenden ganzen Zahlen ab, aber Sie können diesen Bereich als fast überall beginnend interpretieren. "Signed" und "unsigned" sind nur zwei solcher Interpretationen.

Mit anderen Worten, bei 4-Bit-Registern ist die vorzeichenlose Interpretation von "1011" elf, während die vorzeichenbehaftete Interpretation minus fünf ist. Aber es gibt nur einen Wert (den Mathematiker gewöhnlich "elf modulo 2 " nennen, weil Mathematiker traditionsgemäß eine vorzeichenlose Interpretation mögen). Wenn Sie zum Beispiel "0110" zu diesem Wert hinzufügen (was in vorzeichenbehafteten und unsignierten Interpretationen "sechs" bedeutet), erhalten Sie "0001", was der richtige Wert ist: minus fünf plus sechs, eins und elf plus sechs ist siebzehn, die auch gleich eins ist, wenn reduziert Modulo 2 (siebzehn ist eins plus sechzehn; "Reduzieren Modulo 2 " ist über dividieren von sechzehn [das ist 2 ] und den Rest nur behalten).

Eine andere Möglichkeit, dies zu sagen, ist die folgende: Die Anzahl der (binären) Ziffern für einen numerischen Wert ist konzeptionell unendlich links. Das CPU-Register behält nur die 32 am weitesten rechts liegenden Bits. Bei der vorzeichenlosen Interpretation wird herkömmlicherweise angenommen, dass alle Bits ganz links Null sind. Bei der vorzeichenbehafteten Interpretation wird herkömmlicherweise angenommen, dass alle Bits ganz links den gleichen Wert haben wie das Bit 31 (d. H. Alle sind 0 oder alle sind eins). Wie auch immer, wenn Sie eine Addition (oder eine Subtraktion oder eine Multiplikation) durchführen, werden Übertragungen von rechts nach links übertragen, nicht umgekehrt, so dass die Werte dieser ignorierten Bits keinerlei Auswirkungen auf das 32-Bit-Ergebnis haben. Es gibt also nur einen "addieren" -Opcode, der sich nicht im Geringsten darum kümmert, ob seine Operanden im Gehirn des Programmierers "signiert" oder "unsigniert" sind.

Signedness muss bei der Durchführung einer Operation berücksichtigt werden, die nicht kompatibel mit Modulo-Arithmetik ist. Die Umwandlung in eine Folge von Dezimalziffern zur Anzeige ist eine solche Operation. Ein häufiger Fall ist jedoch Vergleiche. Werte modulo 2 sind nicht bestellt; Sie sind in einer Art zyklischen Schleife (wenn Sie 1 bis 2 -1 hinzufügen und Modulo 2 reduzieren, erhalten Sie wieder 0). Vergleiche ergeben nur dann Sinn, wenn Sie ganze Zahlen im ganzen Zahlenbereich berücksichtigen. An diesem Punkt müssen Sie entscheiden, ob Sie die Interpretation mit oder ohne Vorzeichen verwenden. Aus diesem Grund bieten die x86-Prozessoren sowohl jg (Sprung bei größerer, signierter Interpretation) als auch ja (springe wenn darüber, vorzeichenlose Interpretation).

+0

+1 für die umfassendste und generische Antwort. – ruslik