Datentyp
-
Moin
Ich habe folgenden Code:
long long ll; float wert = 1.5; __asm { MOV QWORD PTR[ll], 10 FILD DWORD PTR[ll] FMUL DWORD PTR[wert] FISTP QWORD PTR[ll] }
Doch als Ergebnis kommt für long long ll manchmal das richtige Ergebnis 15, manchmal aber auch irgendein zufälliger, großer Wert raus. Kann mir das mal jemand bitte erklären?
greetz
-
Jeffson schrieb:
Doch als Ergebnis kommt für long long ll manchmal das richtige Ergebnis 15, manchmal aber auch irgendein zufälliger, großer Wert raus. Kann mir das mal jemand bitte erklären?
nein, der Fehler muss auf deiner Seit liegen. Es handlet sich ja um x64 code?
-
Es sieht sowohl nach Gleitkommaproblematik aus, als auch nach Problematik zwischen verschiedenen Formattypen.
a = supervideo
b = superaudio
print a + b...ach was für ein scheiß...;)
Aber sind die Ausgaben gut genug für einen Zufallszahlengenerator?
Und wie sieht eigentlich die Ausgabe genau aus? Soll ein floatwert oder ein (int)long long ausgebeben werden?
-
nachtfeuer schrieb:
Es sieht sowohl nach Gleitkommaproblematik aus, als auch nach Problematik zwischen verschiedenen Formattypen.
a = supervideo
b = superaudio
print a + b...ach was für ein scheiß...;)
genau, was für ein Scheiß den du mal wieder erzählst...
-
Jeffson schrieb:
long long ll; (...) __asm { MOV QWORD PTR[ll], 10 (...) }
Die Variable wird durch
MOV QWORD
nicht richtig initialisiert. Einen solchen Befehl gibt es im 32-Bit-Modus des Prozessors nicht. Der "schlaue" Compiler macht in diesem Fall daraus einMOV BYTE
. Es wird also nur das erste Byte dieser 8-Byte-Variablen initialisiert. Die anderen Bytes können irgendeinen Wert haben.Abhilfe: Initialisierung im C-Programm:
long long ll = 0;
viele grüße
ralph
-
Und wieso macht der compiler diesen befehl zu "mov byte ptr" und nicht "mov dword ptr"?
greetz
-
Jeffson schrieb:
Und wieso macht der compiler diesen befehl zu "mov byte ptr" und nicht "mov dword ptr"?
Warum sollte er?
Besser wäre zu fragen: Warum wirft der Compiler keinen Fehler? Ein "error C2408: illegal type on PTR operator in 'first operand'" zusammen mit einem "warning C4409: illegal instruction size" und einem "warning C4411: 'll' : symbol resolves to displacement register" wäre doch angebracht. Zumindest spuckt der Compiler das aus, wenn ich
MOV KuhWort PTR [ll], 10
programmiere. Er erkennt also ab und zu, dass "MUUUH" nicht "BYTE" heißt.
viele grüße
ralph
-
Na wenn ich ein 32-Bit-System habe, wieso sollte er dann diese Kopieroperation nicht auf DWORD / 4-Byte-Stücke aufteilen (wäre dan halt 2 Mal int)?
-
Jeffson schrieb:
Na wenn ich ein 32-Bit-System habe, wieso sollte er dann diese Kopieroperation nicht auf DWORD / 4-Byte-Stücke aufteilen (wäre dan halt 2 Mal int)?
Das entspricht nicht der erwarteten Arbeitsweise eines Assemblers. Ein Assembler soll den eingegebenen Assemblerbefehl 1:1 in Maschinensprache übersetzen und sich nicht darum kümmern, ob das einen Sinn ergibt oder nicht. Nur so kann der Assemblerprogrammierer die vollständige Kontrolle über die Maschine behalten. Ein anderes Thema ist, ob der Assembler Makros bereithalten soll, um immer wiederkehrende Befehlsfolgen zu generieren.
Die vorgeschlagene Aufteilung könnte zu anderen Problemen führen:
-
Die Ausführung des Befehls ist nicht mehr atomar, d. h. zwischen zwei MOV's könnte ein Interrupt passieren, der dann im schlimmsten Fall eine neue Hälfte der Variable und eine alte Hälfte der Variable zu sehen bekommt.
-
Der Assembler weiß nicht, ob zwischenzeitlich auf 64-Bit umgeschaltet wurde, der 64-Bit-Befehl an dieser Stelle also gewollt und richtig ist. Die beiden 32-Bit-Maschinenbefehle werden dann unter Umständen 64-bittig ausgeführt, was zum Überschreiben von Speicherbereichen oder zum Programmabsturz führen kann.
-
Ein "MOV m64, imm32" hat im 64-Bit-Modus die Bedeutung, dass ein 32-Bit-Wert vorzeichenbehaftet erweitert wird. Ein "MOV m64, imm64" gibt es nicht (soweit ich das auf die Schnelle erblicken kann). Mit zwei "MOV DWORD" ist es also nicht getan. Und das nur, weil der Programmierer einen Denkfehler begangen hat...
-
Es könnte sein, dass der Programmierer gar nicht "MOV QWORD PTR [ll], 10" gemeint hat, sondern nur trickreich eine bestimmte Bytefolge (z.B. ein Passwort) getarnt hat (Obfuscation). Wenn der Assembler nun eigenmächtig etwas anderes daherkompiliert, dann stört er dieses Vorhaben empfindlich.
viele grüße
ralph
-