Präfixe in SSE kombinieren
Frage
In SSE die Präfixe 066h
(Operandengröße Überschreibung) 0F2H
(Repne) und 0F3h
(Repe) sind Teil des Opcode.
In Nicht-sse 066h
Schaltet zwischen 32-Bit (oder 64-Bit) und 16-Bit-Betrieb. 0F2h
und 0F3h
werden für String -Operationen verwendet. Sie können so kombiniert werden 066h
und 0F2h
(oder 0F3h
) kann in derselben Anweisung verwendet werden, da dies aussagekräftig ist. Was ist das Verhalten in einer SSE -Anweisung? Zum Beispiel haben wir (vorerst mod/rm ignorieren):
0f 58
--> addps
66 0f 58
--> addpd
f2 0f 58
--> addsd
f3 0f 58
--> addss
Aber was ist das?
66 f2 0f 58
Und wie wäre es mit?
f2 66 0f 58
Ganz zu schweigen davon, dass zwei widersprüchliche Präfixe der Wiederholungen vorhanden sind:
f2 f3 0f 58
Was ist die Spezifikation für diese?
Lösung
Ich erinnere mich nicht daran, dass ich bei wilder zufälligen Präfixe eine Spezifikation darüber gesehen habe, was Sie erwarten sollten. Ich denke, das CPU-Verhalten kann also "undefiniert" und möglicherweise CPU-spezifisch sein. (Eindeutig sind einige Dinge in den Dokumenten von EG Intel angegeben, aber viele Fälle sind nicht abgedeckt). Und einige Kombinationen können für die zukünftige Verwendung vorbehalten sein.
Meine naiven Annahmen wären im Allgemeinen gewesen, dass zusätzliche Präfixe keine Ops wären, aber es gibt keine Garantie. Dies scheint vernünftig zu sein, da z. B. einige Optimierungshandbücher Multi-byte empfehlen NOP
(Kanonisch 90h
) durch Präfix mit 66h
, z.B:
db 66h, 90h; 2-byte NOP
db 66h, 66h, 90h; 3-byte NOP
db 66h, 66h, 66h, 90h; 4-byte NOP
Das weiß ich jedoch auch CS
und DS
Segment -Override -Präfixe haben neuartige Funktionen als SSE2 -Zweig -Hinweise (Prefixe vorhersagen (Predict Zweig genommen) = 3Eh
= DS
überschreiben; Vorhersage der Zweig nicht genommen = 2Eh
= CS
überschreiben) bei der Anwendung auf bedingte Sprunganweisungen.
Wie auch immer, ich habe mir Ihre Beispiele oben angesehen und immer eingestellt XMM1
an alle 0
und XMM7
an alle 0FFh
durch
pxor xmm1, xmm1 ; xmm1 <- 0s
pcmpeqw xmm7, xmm7 ; xmm7 <- FFs
und dann der fragliche Code mit, mit xmm1, xmm7
Argumente. Was ich beobachtet habe (32 -Bit -Code auf Win64 -System und Intel T7300 Core 2 Duo) war:
1) Keine Änderung beobachtet für addsd
beim Hinzufügen 66h
Präfix
db 66h
addsd xmm1, xmm7 ;total sequence = 66 F2 0F 58 CF
2) Keine Änderung beobachtet für addss
beim Hinzufügen 0F2h
Präfix
db 0f2h
addss xmm1,xmm7 ;total sequence = F2 F3 0F 58 CF
3) Ich habe jedoch eine Änderung durch Präfixen beobachtet addpd
durch 0F2h
:
db 0f2h
addpd xmm1, xmm7 ;total sequence = F2 66 0F 58 CF
In diesem Fall war das Ergebnis in XMM1 0000000000000000FFFFFFFFFFFFFFFFh
Anstatt von FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFh
.
So Meine Schlussfolgerung ist, dass man keine Annahmen treffen und "undefiniertes" Verhalten nicht erwarten sollte. Ich wäre jedoch nicht überrascht, wenn Sie einige Hinweise in Agner Fog's finden könnten Anleitungen.