2015-07-22 10 views
5

(Diese Frage war ursprünglich über die CVTSI2SD Anweisung und die Tatsache, dass ich dachte, dass es nicht auf der Pentium M CPU funktioniert, aber in Wirklichkeit ist es, weil ich ein benutzerdefiniertes Betriebssystem verwende und ich muss SSE manuell aktivieren.)Wie aktiviere ich SSE für meinen freistehenden bootfähigen Code?

Ich habe eine Pentium M CPU und ein benutzerdefiniertes Betriebssystem, die bisher keine SSE-Anweisungen verwendet, aber ich muss sie jetzt verwenden.

Der Versuch, alle SSE-Befehls führt zu einer Unterbrechung 6, illegal opcode auszuführen (was in Linux würde eine SIGILL verursachen, aber das ist nicht Linux), auch in der Intel architectures software developer's manual bezeichnet (was ich von jetzt an als IASDM beziehen) als #UD - Ungültiger Opcode (Undefinierter Opcode).

bearbeiten: Peter Cordes tatsächlich die richtige Ursache identifiziert und wies mich auf die Lösung, die ich weiter unten wieder aufnehmen:

Wenn Sie ein altes Betriebssystem laufen lassen, die nicht XMM regs unterstützt Speicher Bei Kontextwechsel wird das SSE-Aktivierungsbit in einem der Maschinensteuerregister nicht gesetzt.

Tatsächlich erwähnt die IASDM dies:

Wenn ein Betriebssystem nicht ausreichend System-Level-Support für SSE vorsah, kann eine SSE oder SSE2 Befehle ausführt auch #UD erzeugen.

Peter Cordes wies mich auf die SSE OSDev wiki, die beschreibt, wie SSE zu ermöglichen, indem sowohl CR0 und CR4 Steuerregister:

clear the CR0.EM bit (bit 2) [ CR0 &= ~(1 << 2) ] 
set the CR0.MP bit (bit 1) [ CR0 |= (1 << 1) ] 
set the CR4.OSFXSR bit (bit 9) [ CR4 |= (1 << 9) ] 
set the CR4.OSXMMEXCPT bit (bit 10) [ CR4 |= (1 << 10) ] 

Beachten Sie, dass, um in diese Register schreiben zu können, Wenn Sie sich im geschützten Modus befinden, müssen Sie sich in der Berechtigungsstufe 0 befinden. The answer to this question erklärt, wie Sie es testen: Wenn im geschützten Modus, also Bit 0 (PE) in CR0 auf 1 gesetzt ist, können Sie testen Bits 0 und 1 aus dem CS Selektor, der bo sein sollte th 0.

Schließlich muss das benutzerdefinierte Betriebssystem XMM-Register während Kontextwechsel ordnungsgemäß behandeln, indem sie sie bei Bedarf speichern und wiederherstellen.

+0

'CVTSI2SD-Konvertieren Dword-Ganzzahl in skalare Doppelpräzision FP-Wert ' gehört zum SSE2-Befehlssatz, und dies wird in den Intel Software Developer Handbüchern bestätigt. –

+3

"Noch erkennt der Pentium M CVTSI2SD" Quelle nicht? – harold

+0

Ich habe ein Programm, das es verwendet und es auf einem echten Pentium M abstürzt. Auch das Intel Benutzerhandbuch (von denen ich eine Papierkopie habe) enthält diese Anweisung nicht. – anol

Antwort

5

Wenn Sie ein altes oder benutzerdefiniertes Betriebssystem ausführen, das das Speichern von XMM-Regs auf Kontextwechsel nicht unterstützt, hat es die SSE-Aktivierungsbits in den Maschinensteuerregistern nicht gesetzt. In diesem Fall werden alle Anweisungen, die XMM-Regs berühren, fehlerhaft.

Ich brauchte eine Sekunde, um zu finden, aber http://wiki.osdev.org/SSE erklärt, wie CR0 und CR4 geändert werden, damit SSE-Anweisungen auf blankem Metall ohne #UD ausgeführt werden können.


Mein erster Gedanke auf Ihre alte Version der Frage war , dass Sie vielleicht Ihr Programm zusammengestellt mit -mavx, -march=sandybridge oder äquivalent, wodurch der Compiler die VEX-codierte Version von allem zu emittieren.

CVTSI2SD xmm1, xmm2/m32   ; SSE2 
VCVTSI2SD xmm1, xmm2, xmm3/m32 ; AVX 

Siehe https://stackoverflow.com/tags/x86/info für Links, einschließlich Intels insn ref manuell eingestellt.

+0

Ich benutze einen alten GCC und es scheint nicht diese Architektur zu haben. Und ich habe mir die Assembly angeschaut und auch versucht, den Befehl direkt über 'asm()' einzufügen, so dass es wenig wahrscheinlich ist, dass dies der Fall ist. – anol

+1

Es ist -mavx, oops. Schauen Sie sich die Demontage an. Wenn es 'vcvt ...' ist und dein Programm mit SIGILL stirbt, dann ist das ein AVX-Problem. Sonst bekommen Sie wahrscheinlich einen SIGSEGV, nicht SIGILL. Wenn es SIGILL ist, dann passiert etwas Seltsames, und Sie sollten es unter gdb laufen lassen, damit es bei der genauen Anweisung stoppt, die einen Fehler gemacht hat. –

+0

Ich habe versucht, in einem Assembler-Code zu kompilieren, der speziell 'CVTSI2SD' enthält, um sicherzustellen, dass es der Täter ist, und ich habe Unterbrechung 6 bekommen.Aber es ist auch mit "CVTSI2SS" passiert, also ist es eigentlich ein SSE-bezogenes Problem. Anweisungen, die Verweise auf '% xmmN' Register enthalten, funktionieren nicht. – anol

2

Ich schlage vor, dass Sie Intel's manual konsultieren, wenn Sie solche Fragen haben.

Es wird im Handbuch eindeutig gesagt, dass CVTSI2SD eine SSE2-Anweisung ist.

+0

Was meldet CPUID für unterstützte Anweisungen? 'weniger/proc/cpuinfo | grep flags "wenn du auf Linux bist. –

+1

@anol Innerhalb des Handbuchs ist der Abschnitt, den Sie lesen sollten, _Volume 3, Abschnitt 13.1 BETRIEBSSYSTEMUNTERSTÜTZUNG FÜR SSE-ERWEITERUNGEN_. Dieser Abschnitt enthält eine sehr klare Beschreibung und eine Liste, was für SSE-Unterstützung getan werden muss. Michael, du solltest auf jeden Fall einen Hinweis auf diesen Abschnitt in deiner Antwort hinzufügen. –