0から作るソフトウェア開発

日々勉強中。。。

0から作るOS開発

環境準備

環境設定

ブートローダ

カーネルローダ

GRUB

カーネル

ドライバーその他

Tips MMXプログラミング

MMXプログラミング

インテルMMXテクノロジーは、インテルPentiumIIプロセッサファミリーおよびMMXテクノロジーPentiumプロセッサ

でIA-32アーキテクチャーに導入されました。MMXテクノロジーはメディアや通信アプリケーションの処理を高速化

するSIMD(Single-Instruction, Multiple-Data)実行モデルがあります。

MMXテクノロジー概要

MMXテクノロジーは64ビットパックド整数データを処理SIMD実行モデルを定義しています。

SIMD実行モデルを導入することで、IA-32アーキテクチャーに以下の機能が追加されますが、

従来のIA-32アプリケーションやOSとの互換性を維持しています。

MMXテクノロジーには、IA-32アーキテクチャーのすべての実行モード(プロテクティッドモード、

リアルモード、仮想8086モード)からアクセス可能です。MMXテクノロジーの導入で、新しい

実行モードの追加はありません。

MMXテクノロジーのプログラミング環境

MMXテクノロジーには次のような実行環境で実行します。

MMXテクノロジーの実行環境


MMXレジスター

MMXテクノロジーのレジスターは、8 つの64 ビットレジスターがあります。これらのレジスタを使用して、

MMXテクノロジーのパックド整数データ型の計算が実行できます。MMXレジスター内の値は、

メモリ内の64 ビットと同じフォーマットを持ちます。MMXレジスターには、64 ビットアクセスモードと

32 ビットアクセスモードの2 種類のデータアクセスモードがあります。

MMXレジスター


IA-32 アーキテクチャーではMMXレジスターを独立したレジスタとして定義していますが、

実際には FPUデータレジスタスタック(R0 〜 R7)のレジスタ に別名を付けて使用しています。

MMXテクノロジーのデータ型

MMXテクノロジーでは、以下の64 ビットデータ型がIA-32 アーキテクチャに追加されました。

MMX命令は、64 ビットパックドデータ型(パックドバイト、パックドワード、パックド・ダブルワード)と

クワッドワードデータ型を、MMXレジスターとメモリの間またはMMXレジスター同士の間で64 ビット

ブロックで転送します。ただし、MMX命令は、パックドデータ型の算術演算または論理演算を実行する

場合、MMXレジスター内の個々のバイト、ワード、またはダブルワードを並列に処理します。

MMXテクノロジーのデータ型


メモリー内のデータフォルト

メモリーに格納するとき、パックドデータ型のバイト、ワード、ダブルワードが連続したアドレスに

格納されます。最下位のバイト、ワード、ダブルワードが連続するアドレス領域の最下位アドレスに

格納され、最上位のバイト、ワード、ダブルワードが、上位アドレスに格納されます。バイト、ワード、

ダブルワードのメモリへの格納順は常にリトルエンディアン型で、下位アドレスにはデータの下位バイトが

入り、上位アドレスには上位バイトが入ります。

SIMD(Single-Instruction, Multiple-Data)

MMXテクノロジでは、1つの命令で、複数のデータを操作することができます。64ビットのMMXレジスターに

対するバイト、ワード、ダブルワードの算術演算および論理演算は次のような操作(AND、ORなど)を行います

SIMDの操作


例えば、PADDSW命令は、第1オペランドの格納先オペランドの内4つの符号付きワード整数を、

読込元オペランド(第2オペランド)内の4つの符号付きワード整数に加算し、得られた4つのワード整数を

格納先(第1オペランド)に格納します。このようにSIMDは複数のデータ要素に対して同一演算を並列に行うので、

ソフトウェアの処理が効率的になります。MMXテクノロジでは、バイト、ワード、ダブルワードのデータ要素が

MMXレジスターに入っている場合のみ並列演算をサポートします



MMXテクノロジがサポートしているSIMD処理は、メディア、通信、グラフィック関係のアプリケーション用途に適しています

このようなアプリケーションでは、サイズの小さいデータ型(バイト、ワード、ダブルワード)に対して同一演算を膨大な

回数実行するような高度なアルゴリズムを使用しています。例えば、オーディオデータは16ビットのワード単位で

処理を行いますので、MMX命令を使用すれば、1命令で4つのワードデータの演算を同時に実行することができます

また、ビデオやグラフィックのデータは8ビット(バイト)単位のパレットで処理する場合が多くあります

この場合では、8つのバイトデータを同時に演算することができます

MMXの計算方式

整数算術演算を実行したときに、演算結果が範囲外になることがあります。演算結果が範囲外の場合、

データ型が小さくなるので格納先オペランドに格納することができません。例えば、符号付きワード整数の

算術演算実行時に、正のオーバーフローが発生し、符号付きの結果が16ビットより大きくなることがあります



MMXテクノロジは、以下の3つの方法で範囲外の結果を処理します


飽和算術演算のデータ範囲限界値
データ型 下限値 上限値
16進数 10進数 16進数 10進数
符号付きバイト 0x80 -128 0x7F 127
符号付きワード 0x8000 -32,768 0x7FFF 32,767
符号なしバイト 0x00 0 0xFF 255
符号なしワード 0x0000 0 0xFFFF 65,535


飽和算術は、多くのオーバーフローで自然な解が得られます。例えば、カラー計算で飽和算術を

使用すれば、色の反転は起こらないため、色は純粋な黒または白のままとなります。

また、読込元オペランドの範囲チェックをしない場合に、ラップアラウンドによる問題が計算に影響を

及ぼさなくなります。



MMX命令では、例外を発生したりEFLAGSレジスターのフラグをセットすることによってオーバーフローや

アンダーフローを通知することはありません

x87 FPUとの互換性

MMXテクノロジーの状態とはx87 FPU状態の別名で、MMXテクノロジーのサポートするIA-32 アーキテクチャ

のために追加された新規状態でも新規モードでもありません。x87 FPU状態の格納とリストアを行う

浮動小数点命令でもMMXテクノロジー状態を操作することができます。(例えば、コンテキスト

スイッチングの場合など)。MMXテクノロジーでも、x87 FPUとOSとのプログラミング(主にタスクスイッチングで

使用)と同じ技法を使用します。

MMX命令とx87 FPUタグワードの関係

MMX命令の実行後は、必ずx87 FPUタグワード全体が有効(00b)に設定されています。

EMMS命令 (MMXテクノロジー状態のクリア命令)を実行すると、

x87 FPUタグワード全体が空(11b)に設定されます

MMXテクノロジーを利用するアプリケーションの作成

MMXテクノロジーを使用したアプリケーションを作成するときのガイドラインとなります。

MMXテクノロジーがサポートされているかチェックする

アプリケーションは、MMX命令を使用する前に、プロセッサがMMXテクノロジーをサポートしているか

どうかを確認する必要があります。以下の手順でこのチェックを実行します。

  1. CPUID命令 を実行して、プロセッサがCPUID命令をサポートしているかどうか
    チェックします。プロセッサがCPUID命令をサポートしていない場合は、
    無効オペコード例外(#UD)が発生します。

  2. CPUID命令を使用して、MMXテクノロジー機能ビットをチェックし、
    プロセッサがMMXテクノロジーをサポートしているかどうか確認します。
    EAXレジスタの引き数を1 に設定してCPUID 命令を実行し、
    ビット23(MMX テクノロジー)が1 にセットされていることを確認します。

  3. 制御レジスターCR0 内のEMビットが0 に設定されているかどうかチェック
    します。これは、x87 FPU のエミュレーションが無効にされていることを示します。

プロセッサがサポートしていないMMX命令を実行しようとしたり、制御レジスターCR0 のEMビットが

1 に設定されているときにMMX命令を実行しようとすると、無効オペコード例外(#UD)が発生します。

次に、MMXテクノロジーを検出するCPUID命令の使用方法を示します。この例はCPUID命令の

詳細な使用手順ではなく、MMXテクノロジーがサポートされているかどうか検出のための概略です。


    ...                           ; CPUID命令がサポートされているか確認
    ...
    ...                           ; インテルプロセッサの識別
    ...
    MOV     EAX, 1                ; 機能フラグを要求します
    CPUID                         ; 0x0F 0x0A2 CPUID命令
    TEST    EDX, 0x00800000       ; 機能フラグのIA MMXテクノロジービット
                                  ; (EDXのビット23)がセットされているテストします
    JNZ     MMX_Technology_Found



x87 FPU命令とMMX命令間の移行

1 つのアプリケーション内で、x87 浮動小数点命令とMMX命令の両方を使用できます。

ただし、MMXレジスターはx87 FPUレジスタスタックに対して別名参照されるため、x87 FPU命令と

MMX命令の間の移行を行う際は、コヒーレンシのない結果や予期しない結果が発生しないように、

十分に注意する必要があります。(EMMS命令以外の)MMX命令が実行されると、プロセッサは

x87 FPU状態を次のように変更します。

これらの処置の結果、MMX命令の実行以前のx87 FPU状態は、基本的にはすべて失われます。

x87 FPU命令が実行されるとき、プロセッサは、x87 FPUレジスタースタックおよび制御レジスターの

現在の状態が有効であると見なし、x87 FPU状態を変更することなく、x87 FPU命令を実行します。

アプリケーション内でx87 FPU浮動小数点命令とMMX命令の両方を使用する場合は、以下の

ガイドラインに従うことをお勧めします。

EMMS命令の使用方法

MMX命令が実行されると、x87 FPUタグレジスターは有効(00b)とマークされます。この状態で

x87 FPU命令を実行すると、x87 FPUレジスタースタックに有効なデータが入っていると見なされるため、

予期しないx87 FPU浮動小数点例外や誤った結果が発生します。EMMS命令は、クリアされている

ものとしてx87 FPUタグレジスターをマークするしますので、この問題を回避できます。



次のいずれかの場合には、必ずEMMS命令を実行しなければなりません。

MMX命令と、SSE、SSE2、SSE3 を混在させる場合は、EMMS命令を使用する必要はありません。

MMX命令とx87 FPU命令の混在

1 つのアプリケーション内で、x87 FPU浮動小数点命令とMMX命令の両方を使用することができます。

ただし、プロセッサによってはパフォーマンスが低下するため、MMX命令とx87 FPU命令を頻繁に

切り替えることはお勧めしません。MMXテクノロジーコードとx87 FPUコードを混在させる場合は、

以下のガイドラインに従います。

MMXテクノロジーコードのインターフェース

MMX命令を使用して、すべてのMMXレジスターに直接にアクセス可能です。つまり、プロセッサの

汎用レジスター(EAX、EBXなど)と同じインターフェイス規則が、MMXレジスターの使用時にも

適用されます。MMXテクノロジールーチンへの分岐は、MMXレジスターを使用するか、

または(スタックを介して)メモリーアドレスとMMXレジスターを組み合わせて、パラメータと戻り値を

渡します。MMXレジスターを使用してパラメータを渡す場合は、EMMS命令を使用したり、

MMX テクノロジーコードとx87 FPUコードを混在させてはなりません。MMXテクノロジーデータ型を

サポートしない高水準言語を使用する場合は、パックドデータ型を保持する64 ビット構造として、

MMXテクノロジーデータ型を定義できます。高水準言語でMMX命令をコーディングする場合は、

次のような他の手法が使用できます。

マルチタスクOSでのMMXテクノロジーコードの使用

アプリケーションはどのようなマルチタスクOS上で実行されるかを考慮して作成します。

タスクスイッチが発生するときに各タスクはその状態をセーブしておかなければなりません。

プロセッサの状態(コンテキスト)は、汎用レジスタおよび浮動小数点/MMXレジスターで構成されます。



OSには次の2種類があります

非プリエンプティブ・マルチタスクOSでは、コンテキストスイッチの際にFPU状態(または

MMXテクノロジー状態)を保存しません。そのため、直接あるいは間接に制御をOSに返す前に

アプリケーションが自分で必要な状態を保存する必要があります。プリエンプティブマルチタスク

OSでは、コンテキストスイッチの際にFPU状態(またはMMXテクノロジー状態)の保存と復帰を

行います。そのため、アプリケーションが自分でFPU状態(またはMMXテクノロジー状態)の

保存や復帰を行う必要はありません。

MMXテクノロジーコードでの例外処理

MMX命令で発生するメモリーアクセス例外は他のIA-32命令で発生する例外と同じで、

ページフォルト、セグメント不在、境界違反などがあります。MMXテクノロジーコードでは、

既存の例外ハンドラを修正せず使用でき、これらのタイプの例外を処理できます。

保留状態の浮動小数点例外がなければ、MMX命令で数値例外が発生することはありません。

したがって、数値例外を処理するために、既存の例外ハンドラを修正したり、新しい例外

ハンドラを追加する必要はありません。保留状態の浮動小数点例外があるときに、MMX命令を

実行すると数値エラー例外(割込み16 および/ またはFERR#ピンのアサート)が発生します。

例外ハンドラからふきすると、MMX命令が実行を再開します。

レジスターのマッピング

MMXレジスターとそのタグは、浮動小数点レジスタとそのタグにマッピングされています。

MMX命令に対する命令プリフィックスの影響

下記表はMMX命令に対する命令プリフィックスの影響をまとめたものです。予測不可能な動作は、

ある世代のIA-32 プロセッサでは予約済みの動作として扱われ、他の世代のプロセッサでは無効

オペコード例外を発生させることがあります。

MMX命令に対する命令プリフィックスの影響
プリフィックスのタイプ MMX命令に対する影響
アドレスサイズプリフィックス
(0x67)
メモリーオペランドを持つ命令に影響します。
メモリーオペランドを持たない命令では予約済みであり、予測不可能な動作を 発生させます。
オペランドサイズ
(0x66)
予約済みであり、予測不可能な動作を発生させます。
セグメントオーバーライド
(0x2E, 0x36, 0x3E, 0x26, 0x64, 0x65)
メモリーオペランドを持つ命令に影響します。
メモリーオペランドを持たない命令では予約済みであり、予測不可能な動作を 発生させます。
リピートプリフィックス
(0xF3)
予約済みであり、予測不可能な動作を発生させます。
リピートNEプリフィックス
(0xF2)
予約済みであり、予測不可能な動作を発生させます。
ロックプリフィックス
(0xF0)
予約済みであり、無効オペコード(#UD)が発生します。
分岐ヒントプリフィックス
(0x2E, 0x3E)
予約済みであり、予測不可能な動作を発生させます。
命令プリフィックス を参照してください。

inserted by FC2 system