2012-03-26 11 views
2

私はOS開発クラスの宿題プロジェクトに取り組んでいます。 1つのタスクは、割り込み時にSSEレジスタのコンテキストを保存することです。今、コンテキストの保存と復元は簡単です(fxsave/fxsave)。しかし、私はテストに問題があります。同じサンプルの日付をレジスタの1つに入れたいのですが、エラー割り込み6が表示されます。コードはSSEレジスタをロードする

// load some SSE registers 
struct Vec4 { 
    int x, y, z, w; 
} vec = { 0, 1, 2, 3 }; 


asm volatile ( "movl %0, %%eax" 
     : /* no output */ 
     : "r"(&vec) 
     : 
     ); 
asm volatile ("movups (%eax), %xmm0"); 

私はインターネットで検索しました。私が得たのは、それが実効アドレス空間と関係するかもしれないということだけです。しかし、私はそれが何であるか分からない。

+0

この動作をするには、何が必要なのですか?「asm volatile( "movups(0x0)、%xmm0"); ' –

答えて

2

私は問題が何かを発見しました。 SSE命令の実行は、CR0およびCR4レジスタにいくつかのフラグをセットすることによってイネーブルにする必要があります。ここでの詳細:http://wiki.osdev.org/SSE

+1

OSDの最初のルールev:最初に有効にしてから使用します。覚えておいてください。プロセッサは16ビットリアルモードで起動し、ほとんどすべてが無効になっています。8086が開発されたときにはなかったすべてのプロセッサ機能と拡張機能は、起動時に無効になります。 – Griwes

0

これは、必要以上に難しくなっています。たとえば、*mmintrin.hヘッダーの組み込み関数を使用します。

#include <emmintrin.h> 

__m128i vec = _mm_set_epi32(3, 2, 1, 0); 

あなたは、特定のXMMレジスタでこれを置くの出発点として、上記の例を使用する必要がある場合は、ASMを生成し、例えばgcc -Sを使用して、生成されたasmを独自のコードのテンプレートとして使用します。

+0

ありがとう、私は\ * mmintrin.hヘッダーについて知っていますが、それらを使用することはできません。私はこのプロジェクトのために特に作られたカスタムLinuxベースのOSで作業しています。 あなたの例のコードをアセンブリで調べました。それはかなり役に立ちます。今私は、アセンブラを使ってxmm *でデータをロードする方法を知っています。しかし、私が試したような構造体からロードする方法があります。私はそのようなものが必要なので、同じテクニックを適用して、レジスタからデータを取得して印刷することができます。私は、32ビットの各コンポーネントを汎用レジスタに移動して読み出すことでそれができることを知っています。しかし、より効率的な方法が必要です。 –

2

インラインアセンブリでメモリオペランドをという制約として使用する必要があります。これは、アドレスがripの相対または再配置可能な場合は後者が機能しないため、自分でアドレスを生成して(&演算子で試した)、レジスタにロードするよりもはるかに優れています。

asm volatile ("movups %0, %%xmm0" 
     : /* no output */ 
     : "m"(vec) 
     : 
     ); 

そして、2つの "%%"の前にレジスタ名を使用する必要があります。

gccの制約の詳細は、http://gcc.gnu.org/onlinedocs/gcc/Simple-Constraints.html#Simple-Constraintsを参照してください。この概念は単純ではありません:-)

+0

動作しませんでした。私はまだ中断しています6. :( –

+0

私にはXYの問題のように聞こえます – hirschhornsalz

+0

xmm *レジスタを構造体からロードし、割り込みを生成し、xmm *レジスタのコンテキストを保存し、状態を編集して割り込みを処理する方法が必要ですGRUBが実行をOSに渡した後、システムを制御するだけの基本的なOSであり、テキストを印刷します。 GPUメモリに直接アクセスして割り込みを処理すること(これは私の実装するタスクです) –

関連する問題