x86 アーキテクチャ

eax

アキュムレータ

ebx

基本レジスタ

ecx

カウンターの登録

edx

データレジスタ-i/o ポートアクセスと算術関数に使用できます。

esi

ソースインデックスレジスタ

修飾子

コピー先のインデックスレジスタ

ebp

ベースポインターレジスタ

esp

スタック ポインター

すべての整数レジスタは32ビットです。 ただし、その多くには、16ビットまたは8ビットのサブレジスタがあります。

ax

Eaxの下位16ビット

bx

Ebxの下位16ビット

cx

Ecxの下位16ビット

dx

Edxの下位16ビット

si

Esiの下位16ビット

di

下位16ビットの edi

bp

低16ビットの ebp

プロセッサー

低16ビットの esp

ウムアルクラ

Eaxの下位8ビット

ah

高8ビットの ax

bl

Ebxの低8ビット

bh

高8ビットの bx

付い

Ecxの低8ビット

ch

高8ビットの cx

dl

Edxの下位8ビット

dh

高8ビットの dx

Subregister での操作は、subregister にのみ影響し、サブレジスタの外部にあるパーツは一切影響を及ぼしません。 たとえば、 ax レジスタに格納すると、 eax レジスタの上位16ビットが変更されずに残ります。

を使用する場合 (式の評価) コマンドでは、登録の先頭に "at" 記号 () を付ける必要があり ます。 たとえば、? axではなく、 ? @axを使用する必要があります。 これにより、デバッガーは、シンボルではなくレジスタとして ax を認識します。

ただし、 r (レジスタ) コマンドでは、(@) は必要ありません。 たとえば、 r ax = 5 は常に正しく解釈されます。

他の2つのレジスタは、プロセッサの現在の状態にとって重要です。

eip

命令ポインター

flags

flags

命令ポインターは、実行される命令のアドレスです。

Flags register は、1ビットのフラグのコレクションです。 命令の結果を記述するために、多くの命令によってフラグが変更されます。 これらのフラグは、条件付きジャンプ命令によってテストできます。 詳細については、「 X86 フラグ 」を参照してください。

呼び出し規約

X86 アーキテクチャには、いくつかの異なる呼び出し規約があります。 幸いにも、これらはすべて同じレジスタの保存と関数の戻り値に従います。

  • 関数は、 eaxecx、および edxを除くすべてのレジスタを保持する必要があります。これは関数呼び出しで変更でき、 espは呼び出し規約に従って更新する必要があります。

  • 結果が32ビット以下の場合、 eax レジスタは関数の戻り値を受け取ります。 結果が64ビットの場合、結果は edx: eax ペアに格納されます。

X86 アーキテクチャで使用される呼び出し規則の一覧を次に示します。

  • Win32 (__stdcall)

    関数のパラメーターはスタックで渡され、右から左にプッシュされ、呼び出し先がスタックを消去します。

  • ネイティブ C++ メソッド呼び出し (thiscall とも呼ばれます)

    関数のパラメーターはスタックで渡され、右から左にプッシュされ、"this" ポインターが ecx レジスタに渡され、呼び出し先がスタックを消去します。

  • COM (C++ メソッド呼び出しの__stdcall )

    関数のパラメーターはスタックで渡され、右から左にプッシュされた後、"this" ポインターがスタックにプッシュされた後、関数が呼び出されます。 呼び出し先がスタックを消去します。

  • __fastcall

    最初の2つの DWORD または小さい引数は、 ecx および edx レジスタに渡されます。 残りのパラメーターはスタックで渡され、右から左にプッシュされます。 呼び出し先がスタックを消去します。

  • __cdecl

    関数のパラメーターはスタックで渡され、右から左にプッシュされ、呼び出し元がスタックを消去します。 __Cdecl呼び出し規約は、可変長パラメーターを持つすべての関数に使用されます。

レジスタとフラグのデバッガー表示

デバッガーレジスタの表示の例を次に示します。

eax=00000000 ebx=008b6f00 ecx=01010101 edx=ffffffff esi=00000000 edi=00465000
eip=77f9d022 esp=05cffc48 ebp=05cffc54 iopl=0         nv up ei ng nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000286

ユーザーモードのデバッグでは、 iopl と、デバッガー表示の最後の行全体を無視できます。

x86 フラグ

前の例では、2行目の末尾にある2文字のコードが フラグです。 これらはシングルビットレジスタで、さまざまな用途があります。

次の表に、x86 フラグの一覧を示します。

フラグコードフラグ名値フラグステータスステータス説明

オーバーフローフラグ

0 1 nvov

オーバーフローオーバーフロー dfなし

方向フラグ

0 1 updn

Ifの方向方向

割り込みフラグ

0 1 diei

無効な割り込みが有効になっている sf

符号フラグ

0 1 plng

正 (またはゼロ) のマイナス zf

ゼロフラグ

0 1 nzzr

0以外の af

補助キャリーフラグ

0 1 naac

補助キャリーのキャリー pfがありません

パリティフラグ

0 1 pepo

パリティ 偶数パリティ (奇数)

キャリーフラグ

0 1 nccy

キャリーを受けていません

トラップフラグ

Tfが1に等しい場合、プロセッサは1つの命令の実行後に STATUS_SINGLE_STEP の例外を発生させます。 このフラグは、シングルステップのトレースを実装するためにデバッガーによって使用されます。 他のアプリケーションでは使用できません。

iopl

I/o 特権レベル

これは、0 ~ 3 の値を持つ2ビット整数です。 これは、ハードウェアへのアクセスを制御するためにオペレーティングシステムによって使用されます。 アプリケーションでは使用しないでください。

デバッガーコマンドウィンドウの一部のコマンドの結果としてレジスタが表示される場合は、表示されている フラグの状態 になります。 ただし、 r (レジスタ) コマンドを使用してフラグを変更する場合は、 フラグコードでそれを参照する必要があります。

WinDbg の [レジスタ] ウィンドウでは、フラグコードを使用してフラグを表示または変更します。 フラグの状態はサポートされていません。

次に例を示します。 上記のレジスタ表示には、フラグステータス ng が表示されます。 これは、符号フラグが現在1に設定されていることを意味します。 これを変更するには、次のコマンドを使用します。

r sf=0

これにより、符号フラグが0に設定されます。 別の登録を表示した場合、 ng ステータスコードは表示されません。 代わりに、 pl ステータスコードが表示されます。

Sign フラグ、0フラグ、およびキャリーフラグは、最も一般的に使用されるフラグです。

照明

条件は、1つまたは複数のフラグの状態を表します。 X86 でのすべての条件付き操作は、条件に基づいて表現されます。

アセンブラーは、1文字または2文字の省略形を使用して条件を表します。 条件は、複数の省略形で表すことができます。 たとえば、AE ("上または等しい") は、NB と同じ条件です ("次の値ではありません")。 次の表に、一般的な条件とその意味を示します。

条件名 フラグ 説明

Z

ZF = 1

最後の操作の結果が0でした。

NZ

ZF = 0

最後の操作の結果が0ではありませんでした。

C

CF = 1

最後の操作には、キャリーまたは借りるが必要です。 符号なし整数の場合は、オーバーフローを示します。

NC

CF = 0

最後の操作では、キャリーまたは借りるは必要ありませんでした。 符号なし整数の場合は、オーバーフローを示します。

S

SF = 1

最後の操作の結果には、上位ビットが設定されます。

NS

SF = 0

最後の操作の結果は、高いビットクリアになります。

O

= 1

符号付き整数演算として処理された場合、最後の操作でオーバーフローまたはアンダーフローが発生しました。

NO

= 0

符号付き整数演算として処理された場合、最後の操作でオーバーフローまたはアンダーフローは発生しませんでした。

条件を使用して、2つの値を比較することもできます。 Cmp命令は、2つのオペランドを比較し、一方のオペランドをもう一方のオペランドから減算した場合と同様にフラグを設定します。 次の条件を使用して、 cmpvalue1, value2の結果を確認できます。

条件名 フラグ CMP 操作後の意味です。

E

ZF = 1

value1value2

NE

ZF = 0

value1 ! = value2

GE NL

SF = OF

value1= value2。 値は符号付き整数として扱います。

LE NG

ZF=1 または SF!=OF

value1= value2。 値は符号付き整数として扱います。

G NLE

ZF=0 および SF=OF

value1value2。 値は符号付き整数として扱います。

L NGE

SF!=OF

value1value2。 値は符号付き整数として扱います。

AE NB

CF=0

value1= value2。 値は符号なし整数として扱います。

BE NA

CF=1 または ZF=1

value1= value2。 値は符号なし整数として扱います。

A NBE

CF=0 および ZF=0

value1value2。 値は符号なし整数として扱います。

B NAE

CF=1

value1value2。 値は符号なし整数として扱います。

条件は、通常 、cmp 命令またはテスト命令の結果に作用するために 使用 されます。 たとえば、オブジェクトに適用された

cmp eax, 5
jz equal

は、式 ( eax - 5) を計算し、結果に従ってフラグを設定することで、eax レジスタを数値 5 と比較します。 減算の結果が 0 の場合 、zr フラグが設定され 、jz 条件が true に設定され、ジャンプが実行されます。

データ型

  • byte: 8 ビット

  • word: 16 ビット

  • dword: 32 ビット

  • qword: 64 ビット (浮動小数点の倍精度を含む)

  • 2 つ目: 80 ビット (浮動小数点拡張倍精度を含む)

  • oword: 128 ビット

表記

次の表は、アセンブリ言語命令の記述に使用される表記を示しています。

表記 説明

r、r1、r2...

レジスタ

m

メモリ アドレス (詳細については、「次のアドレス指定モード」セクションを参照してください)。

#n

イミディエイト定数

r/m

登録またはメモリ

r/#n

登録定数または即時定数

r/m/#n

レジスタ、メモリ、または即時定数

cc

前の「条件」セクションに記載されている条件コード。

T

"B"、"W"、または "D" (byte、word、または dword)

accT

サイズTアキュムレータ: t = "B" の場合はal、Tが "W" の場合はax、Tが "D" の場合はeax

アドレス指定モード

アドレス指定モードは複数ありますが、すべてT ptr [expr]という形式になります。Tは何らかのデータ型 (前の「データ型」セクションを参照)、expr は定数とレジスタを含む式です。

ほとんどのモードの表記は、大きな問題なく引き起こされる可能性があります。 たとえば、BYTE PTR [esi+edx*8+3]は、"esiレジスタの値を取得し、edxレジスタの 8 倍の値を追加し、3 つを追加してから、結果のアドレスでバイトにアクセスする" という意味です。

パイプライン

Pentium は 2 つの問題です。つまり、1 クロック ティックで最大 2 つのアクションを実行できます。 ただし、一度に 2 つのアクション (ペアリングと呼 ばれる)を実行できる場合の規則は非常に複雑です。

x86 は CISC プロセッサなので、ジャンプ遅延スロットについて心配する必要はありません。

同期されたメモリ アクセス

読み込み、変更、および格納の命令は、ロック プレフィックスを受け取る可能性があります。このプレフィックスは、次のように命令を変更します。

  1. 命令を発行する前に、CPU によって保留中のすべてのメモリ操作がフラッシュされ、一貫性が確保されます。 すべてのデータ プリフェッチは破棄されます。

  2. 命令を発行すると、CPU はバスに排他的にアクセスできます。 これにより、読み込み/変更/ストア操作のアトミック性が確保されます。

xc xc xc 命令は、値をメモリと交換するたびに、前の規則に自動的に従います。

それ以外の手順はすべて既定で非ロックです。

ジャンプ予測

無条件ジャンプが実行されると予測されます。

条件付きジャンプは、最後に実行された時刻に取得されたかどうかに応じて、取得または取得されないと予測されます。 ジャンプ履歴を記録するキャッシュのサイズは制限されています。

CPU に、条件付きジャンプが最後に実行されたかどうかの記録が存在しない場合は、条件付きジャンプが取得されたと予測され、条件付きジャンプが取得されていないと予測されます。

配置

x86 プロセッサは、パフォーマンスが低下した場合に、アロケーションされていないメモリ アクセスを自動的に修正します。 例外は発生しません。

アドレスがオブジェクト サイズの倍数の整数である場合、メモリ アクセスはアラインされたと見なされます。 たとえば、すべての BYTE アクセスがアラインされ (すべてが 1 の整数倍数)、さらにアドレスへの WORD アクセスがアラインされ、DWORD アドレスがアラインされるには 4 の倍数である必要があります。

ロック プレフィックス は、アリストされていないメモリ アクセスには使用できません。

Intel x86 プロセッサでは、複雑な命令セット コンピューター (CISC) アーキテクチャが使用されます。つまり、汎用レジスタが大量に使用されるのではなく、特別な目的のレジスタが少なめからなっています。 また、複雑な特殊な目的の命令が主に使用されます。

x86 プロセッサは、少なくとも 8 ビット Intel 8080 プロセッサまでその歴史をトレースします。 x86 命令セットの多くの旧式は、そのプロセッサ (および Zilog Z-80 バリアント) との下位互換性が原因です。

Microsoft Win32 は、32 ビット フラット モードで x86 プロセッサを使用します。 このドキュメントでは、フラット モードにのみ焦点を当てる必要があります。

レジスタ

x86 アーキテクチャは、次の特権のない整数レジスタで構成されています。