IA-32 インテル ®
5.7.4. SSE2 キャッシュ制御命令と命令順序付け命令
SSE2キャッシュ制御命令は、XMMレジスタからメモリにデータをストアするときの非テンポラル・
データのキャッシュ処理の制御を強化する。LFENCE命令とMFENCE命令は、ストア操作時の命令 の順序の制御を強化する。
CLFLUSH Flushes and invalidates a memory operand and its associated cache line from all levels of the processor’s cache hierarchy.
LFENCE Serializes load operations.
MFENCE Serializes load and store operations.
PAUSE Improves the performance of “spin-wait loops.”
MASKMOVDQU Non-temporal store of selected bytes from an XMM register into memory.
MOVNTPD Non-temporal store of two packed double-precision floating-point values from an XMM register into memory.
MOVNTDQ Non-temporal store of double quadword from an XMM register into memory.
MOVNTI Non-temporal store of a doubleword from a general-purpose register into memory.
5 .8 . システム命令
次に挙げるシステム命令はプロセッサの機能を制御するために使用するもので、オペレーティング・
システムやエグゼクティブのサポート用に用意されている。
LGDT Load global descriptor table (GDT) register SGDT Store global descriptor table (GDT) register LLDT Load local descriptor table (LDT) register SLDT Store local descriptor table (LDT) register
LTR Load task register
STR Store task register
LIDT Load interrupt descriptor table (IDT) register SIDT Store interrupt descriptor table (IDT) register MOV Load and store control registers
LMSW Load machine status word
SMSW Store machine status word
CLTS Clear the task-switched flag ARPL Adjust requested privilege level
LAR Load access rights
LSL Load segment limit
VERR Verify segment for reading
VERW Verify segment for writing
MOV Load and store debug registers INVD Invalidate cache, no writeback WBINVD Invalidate cache, with writeback
INVLPG Invalidate TLB Entry
LOCK (prefix) Lock Bus
HLT Halt processor
RSM Return from system management mode (SSM) RDMSR Read model-specific register
WRMSR Write model-specific register
RDPMC Read performance monitoring counters
RDTSC Read time stamp counter
SYSENTER Fast System Call, transfers to a flat protected mode kernel at CPL=0.
SYSEXIT Fast System Call, transfers to a flat protected mode kernel at CPL=3.
6
プロシージャ・コール、
割り込み、例外
プロシージャ・コール、割り込み、例外
第6章では、プロシージャやサブルーチンのコールを実行するためにIA-32アーキテクチャに用意さ れている機能について説明する。また、割り込みや例外が、アプリケーション・プログラマの視点 から見てどのように処理されるかについても説明する。
6 .1 . プロシージャ・コールのタイプ
プロセッサは、プロシージャ・コールを次の2つの方法でサポートする。
•
CALL命令およびRET命令。•
ENTER命令およびLEAVE命令。CALL命令およびRET命令と併用。これらのプロシージャ・コールの機構はいずれも、プロシージャ・スタック(通常は単にスタック と呼ぶ)を使用して、コール元のプロシージャのステートをセーブし、パラメータをコールされた プロシージャに渡し、現在実行されているプロシージャのローカル変数を格納する。
割り込みや例外を処理するためのプロセッサの機能は、CALL命令やRET命令が使用する機能と同 じである。
6 .2 . スタック
スタック(図6-1.を参照)は、連続するメモリ・ロケーションの配列である。このスタックはセグ メント内に格納され、SSレジスタ内のセグメント・セレクタによって識別される。(フラット・メモ リ・モデルを使用する場合は、スタックはプログラム用のリニア・アドレス空間の任意の場所に配 置できる。)1つのスタックは、セグメントの最大サイズである4Gバイトまでのサイズを持つことが できる。
スタック上で次に使用可能なメモリ・ロケーションは、「スタックのトップ」と呼ばれる。スタック のトップのアドレス(すなわち、SSセグメントのベースからのオフセット)は、常に、ESPレジス タに格納されているスタック・ポインタが示している。
スタック上にアイテムを配置する場合はPUSH命令を、スタックから取り出す場合はPOP命令を使 用する。あるアイテムをスタックにプッシュする場合は、プロセッサはまずESPレジスタをデクリ メントし、次にそのアイテムを新たにスタックのトップに書き込む。アイテムをスタックからポッ プする場合は、プロセッサはスタックのトップからアイテムを読み取り、次にESPレジスタをイン クリメントする。このように、アイテムをスタックにプッシュした場合はスタックはメモリの下位 アドレスに向かって拡大し、アイテムをスタックからポップした場合はスタックは上位アドレスに 向かって縮小されることになる。
プログラムやオペレーティング・システムあるいはエグゼクティブにおいては、多数のスタックを セットアップできる。たとえば、マルチタスク・システムでは、それぞれのタスクが別々にスタッ クを持つことができる。システム内に設定できるスタックの数は、セグメントの最大数と、使用可 能な物理メモリとによって制限される。ただし、システムが多数のスタックをセットアップした場
合でも、特定の時点で使用できるスタックは1つ(すなわち現在のスタック)だけである。「現在の スタック」とは、SSレジスタが参照するセグメント内に格納されているスタックである。
プロセッサは、あらゆるスタック操作に対して自動的にSSレジスタを参照する。たとえば、ESPレ ジスタがメモリ・アドレスとして使用されている場合は、SSレジスタは現在のスタック内のアドレ スを自動的にポイントする。また、CALL、RET、PUSH、POP、ENTER、LEAVEの各命令もすべて、
現在のスタックに対して操作を実行する。
6.2.1. スタックのセットアップ
スタックをセットし、それを現在のスタックとして設定するには、プログラムやオペレーティング・
システムあるいはエグゼクティブは次の操作を実行しなければならない。
1. スタック・セグメントを設定する。
2. MOV、POP、LSS のいずれかの命令を使用して、スタック・セグメントのセグメント・セレク タをSSレジスタにロードする。
図6-1. スタックの構造
スタックのボトム (Initial ESP Value)
コール元プロ シージャの ローカル変数
コールされる プロシージャ に渡される パラメータ フレーム境界
EBP レジスタ ESP レジスタ リターン命令ポインタ
スタックのトップ スタック・セグメント
プッシュを行うと スタックのトップが 下位アドレスに移る。
ポップを行うと スタックのトップが 上位アドレスに移る。
EBPレジスタは、一般には スタックは16ビット幅 あるいは32ビット幅。
リターン命令ポインタを ポイントするようセット アップされる。
3. MOV、POP、LSSのいずれかの命令を使用して、スタックのスタック・ポインタをESPレジス タにロードする。(LSS命令を使用すれば、1つの操作でSSレジスタとESPレジスタをロード できる。)
セグメント・ディスクリプタをセットアップする方法や、スタック・セグメントに対するセグメン トの制限については、『IA-32 インテル®アーキテクチャ・ソフトウェア・デベロッパーズ・マニュア ル、下巻』の第3章「セグメント・ディスクリプタ」を参照のこと。
6.2.2. スタックのアライメント
スタック・セグメントのスタック・ポインタは、スタック・セグメントの幅によって16ビット(ワー ド)境界か32ビット(ダブル・ワード)境界のいずれかにアライメントを揃えなければならない。
スタック・セグメントの幅は、現行コード・セグメントのセグメント・ディスクリプタ内にあるD フラグによってセットされる(『IA-32 インテル®アーキテクチャ・ソフトウェア・デベロッパーズ・
マニュアル、下巻』の第3章にある「セグメント・ディスクリプタ」を参照)。PUSH命令とPOP命 令では、プッシュ操作やポップ操作に対してスタック・ポインタをデクリメントしたりインクリメ ントする量は、Dフラグによって決まる。スタック幅が16ビットの場合は、スタック・ポインタは
16ビットずつインクリメントまたはデクリメントされる。スタック幅が32ビットの場合は、スタッ
ク・ポインタは32ビットずつインクリメントまたはデクリメントされる。16ビット値を32ビット幅 のスタックにプッシュすると、スタックのアライメントのずれが発生する(つまり、スタック・ポ インタのアライメントがダブルワード境界に合わなくなる)。ただし、セグメント・レジスタ(16 ビット・セグメント・セレクタ)の内容を32ビット幅のスタックにプッシュした場合は例外である。
この場合は、プロセッサが自動的に、スタック・ポインタのアライメントを次の32ビット境界に合 わせる。
プロセッサは、スタック・ポインタのアライメントはチェックしない。スタック・ポインタのアラ イメントを適切に維持するためには、プロセッサ上で動作しているプログラム、タスク、およびシ ステム・プロシージャによって行う。スタック・ポインタのアライメントが正しく行われていない と、処理能力が極端に低下するばかりでなく、場合によってはプログラム障害が発生する。
6.2.3. スタック・アクセスにおけるアドレス・サイズ属性
PUSH命令やPOP命令などの暗黙的にスタックを使用する命令では、それぞれが16ビットまたは32
ビットの2つのアドレス・サイズ属性を持つ。その理由は、これらの命令が暗黙的にスタックのトッ プのアドレスを必ず持っており、場合によっては明示的なメモリ・アドレス(たとえば、PUSH Array1[EBX])も持つこともあるためである。明示的なアドレスの属性は、現行コード・セグメント のDフラグと、67Hのアドレス・サイズ・プリフィックスによって決まる。
スタック・アクセスにおいてSPかESPのどちらが使用されるかは、スタックのトップのアドレス・
サイズ属性で決まる。16ビットのアドレス・サイズ属性を持つスタック操作では、16ビットのSPス タック・ポインタ・レジスタを使用して、最大スタック・アドレスとしてFFFFHまで使用できる。
一方、32ビットのアドレス・サイズ属性を持つスタック操作では、32ビットのESPレジスタを使用 して、最大スタック・アドレスとしてFFFFFFFFHまで使用できる。スタックとして使用されるデー タ・セグメントについてのデフォルトのアドレス・サイズ属性は、セグメントのディスクリプタの Dフラグによって制御される。このフラグがクリアされている場合は、デフォルトのアドレス・サ イズ属性は16ビットになる。このフラグがセットされている場合は、アドレス・サイズ属性は32 ビットになる。