IA-32 インテル ®
6.5.2. LEAVE 命令
LEAVE命令は、直前のENTER命令と逆の動作を行う。LEAVE命令はオペランドは持たず、EBPレ
ジスタの内容をESPレジスタにコピーし、プロシージャに割り当てられたスタック空間すべてを開 放する。次に、スタックからEBPレジスタの古い値をリストアする。このとき同時に、ESPレジス タも元の値にリストアされる。したがって、LEAVE命令の後でRET命令を使用すれば、プロシー ジャで使用するためにコール元プログラム上でスタックにプッシュしておいた引き数とリターン・
アドレスを削除することができる。
図6-10. プロシージャCに移行後のスタック・フレーム
EBP ディスプレイ
古いEBP
ESP メインのEBP
動的記憶領域
プロシージャAのEBP メインのEBP メインのEBP
プロシージャAのEBP
プロシージャAのEBP メインのEBP プロシージャAのEBP
プロシージャAのEBP
プロシージャAのEBP メインのEBP プロシージャAのEBP
7
汎用命令による
プログラミング
汎用命令によるプログラミング
汎用命令は、IA-32命令のうち、Intel IA-32プロセッサ向けの基本命令セットに相当する。これら の命令は、最初のIA-32プロセッサ(Intel 8086とIntel 8088)でIA-32アーキテクチャに導入され た。これ以降のIA-32プロセッサ・ファミリ(Intel 286プロセッサ、Intel 386プロセッサ、Intel 486 プロセッサ、Pentiumプロセッサ、Pentium Proプロセッサ、およびPentium IIプロセッサ)で、こ の汎用命令セットに対して新しい命令が追加された。
汎用命令は、整数データ型、ポインタ・データ型、およびBCDデータ型に対して、基本的なデータ 転送、メモリ・アドレス指定、算術演算と論理演算、プログラム・フロー制御、入出力、およびス トリング操作を実行する。
本章では、汎用命令の概要について説明する。これらの命令についての詳細は、『IA-32 インテル® アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル、中巻』の第3章「命令セット・
リファレンス」を参照のこと。
7 .1 . 汎用命令のプログラミング環境
汎用命令のプログラミング環境は、IA-32アーキテクチャの基本実行環境を構成する一連のレジスタ およびアドレス空間(図7-1.を参照)と、一連のデータ型で構成される。基本実行環境には、以下 の項目が含まれる。
•
汎用レジスタ。8つの32ビット汎用レジスタ(図3-4.を参照)と既存のIA-32アドレス指定モー ドを組み合わせて、メモリ内のオペランドをアドレス指定する。これらのレジスタは、EAX、EBX、ECX、EDX、EBP、ESI、EDI、およびESPという名前で参照される。
•
セグメント・レジスタ。6つの16ビット・セグメント・レジスタが、メモリへのアクセスに使 用されるセグメント・ポインタを格納する。これらのレジスタは、CS、DS、SS、ES、FS、お よびGSという名前で参照される。•
EFLAGSレジスタ。この32ビット・レジスタ(図3-7.を参照)は、基本的な算術演算、比較演算、およびシステム操作を制御し、各操作のステータスを示す。
•
EIPレジスタ。この32ビット・レジスタは、現在の命令ポインタを格納する。汎用命令は、以下のデータ型を操作する。
•
バイト、ワード、およびダブルワード(図4-1.を参照)•
符号付きおよび符号なしバイト、ワード、およびダブルワード整数(図4-3.を参照)•
nearポインタとfarポインタ(図4-4.を参照)•
ビット・フィールド(図4-5.を参照)•
BCD整数(図4-8.を参照)7 .2 . 汎用命令の概要
汎用命令は、以下の11のグループに分けられる。
•
データ転送命令•
2進算術命令•
10進算術命令•
論理演算命令•
シフト命令とローテート命令•
ビット命令とバイト命令•
制御転送命令•
ストリング命令•
フラグ制御命令•
セグメント・レジスタ命令•
その他の命令図7-1. 汎用命令の基本実行環境
0 232 -1
アドレス空間
汎用レジスタ
EIP(命令ポインタ・レジスタ)
EFLAGSレジスタ
セグメント・
32ビット 32ビット 8個(32ビット)
レジスタ 6個(16ビット)
以下の各項では、これらの命令について説明する。
7.2.1. データ転送命令
データ転送命令は、メモリとプロセッサ・レジスタの間およびレジスタ同士の間で、バイト、ワー ド、ダブルワード、またはクワッドワードを転送する。これらの命令は、以下の4つのサブグループ に分けられる。
•
汎用データ転送命令•
交換命令•
スタック操作命令•
型変換命令7.2.1.1. 汎用データ転送命令
転送命令。MOV (move)命令とCMOVcc (conditional move)命令は、メモリとレジスタの間またはレジ スタ同士の間でデータを転送する。
MOV命令は、メモリとプロセッサ・レジスタの間の基本的なデータ・ロード/データ・ストア操作 と、レジスタ間のデータ転送操作を実行する。この命令は、表7-1.に示したパス上のデータ転送を 処理する(コントロール・レジスタおよびデバッグ・レジスタとの間のデータの転送については、
『IA-32 インテル®アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル、中巻』の第3章の
「MOV - コントロール・レジスタとの間の転送」と「MOV - デバッグ・レジスタとの間の転送」を参照)。 MOV命令は、あるメモリ・ロケーションから他のメモリ・ロケーションにデータを転送することや、
あるセグメント・レジスタから他のセグメント・レジスタにデータを転送することはできない。メ モリからメモリへの転送は、MOVS (string move)命令で実行する必要がある(7.2.8.項「ストリング の操作」を参照)。
条件付き転送命令。CMOVcc 命令は、EFLAGSレジスタ内のステータス・フラグの状態をチェック し、フラグが指定の状態(または条件)である場合に転送動作を実行する命令グループである。こ れらの命令を使用して、メモリから汎用レジスタに、またはある汎用レジスタから他の汎用レジス タに、16ビットまたは32ビットの値を転送できる。各命令でテストされるフラグの状態は、その命 令に関連する条件コード(cc )で指定される。指定の条件が満たされない場合は、転送は実行され ず、CMOVcc 命令の次の命令からプログラムの実行が再開される。
表7-1. 転送命令の動作
データ転送のタイプ ソース → デスティネーション メモリからレジスタへ メモリ・ロケーション → 汎用レジスタ
メモリ・ロケーション → セグメント・レジスタ レジスタからメモリへ 汎用レジスタ → メモリ・ロケーション
セグメント・レジスタ → メモリ・ロケーション
表7-2.は、CMOVcc 命令のニーモニックと、各命令でテストされる条件を示している。CMOVcc 命 令のニーモニックは、"CMOV"に条件コード・ニーモニックを付加したものである。表7-2.にペアで 示した命令(例えば、CMOVA/CMOVNBE)は、同じ命令の別名である。アセンブラは、プログラ ム・リストが読みやすくなるように、これらの別名を用意している。
CMOVcc 命令によって、小さなIF構造を削減するのに便利である。また、CMOVcc 命令を使用して、
IF文による分岐のオーバーヘッドとプロセッサによる分岐の予測ミスの可能性を減らすことができ る。
これらの条件付き転送命令は、P6ファミリ・プロセッサとPentium 4プロセッサ・ファミリでのみサ ポートされている。ソフトウェアは、CPUID命令を使用してプロセッサの機能情報をチェックする ことによって、CMOVcc 命令がサポートされているかどうかを確認できる(『IA-32 インテル®アー キテクチャ・ソフトウェア・デベロッパーズ・マニュアル、中巻』の第3章の「CPUID - CPUの識 別」を参照)。
7.2.1.2. 交換命令
交換命令は、1つ以上のオペランドの内容を入れ替える。場合によっては、LOCK信号のアサートや、
EFLAGSレジスタ内のフラグの変更などの追加の操作も実行する。
XCHG (exchange)命令は、2つのオペランドの内容を入れ替える。この命令は、3つのMOV命令と同
じ効果を持つが、一方のオペランドをロードする間に他方のオペランドの内容を保存するための一 時的なロケーションを必要としない。XCHG命令でメモリ・オペランドを処理するときは、プロセッ サのLOCK信号が自動的にアサートされる。この命令は、プロセスの同期をとるためにセマフォま たは同様のデータ構造を実装するのに便利である(バス・ロックについての詳細は、『IA-32 インテ ル®アーキテクチャ・ソフトウェア・デベロッパーズ・マニュアル、下巻』の第7章の「バス・ロッ ク」を参照)。
BSWAP (byte swap)命令は、32ビット・レジスタ・オペランドのバイト・オーダを反転する。ビット
位置0〜7は24〜31で置き換えられ、ビット位置8〜15は16〜23で置き換えられる。この命令を2 回続けて実行すると、レジスタは前と同じ値になる。BSWAP命令は、「ビッグ・エンディアン」デー タ・フォーマットと「リトル・エンディアン」データ・フォーマットの変換に便利である。また、こ の命令によって、10進算術演算の実行を高速化することができる(XCHG命令を使用して、ワード 内の上位バイトと下位バイトを入れ替えることができる)。
レジスタ同士の間 汎用レジスタ → 汎用レジスタ 汎用レジスタ → セグメント・レジスタ セグメント・レジスタ → 汎用レジスタ 汎用レジスタ → コントロール・レジスタ コントロール・レジスタ → 汎用レジスタ 汎用レジスタ → デバッグ・レジスタ デバッグ・レジスタ → 汎用レジスタ 即値データからレジスタへ 即値 → 汎用レジスタ
即値データからメモリへ 即値 → メモリ・ロケーション
表7-1. 転送命令の動作 (続き)
データ転送のタイプ ソース → デスティネーション