2011-04-21 12 views
5

私はアセンブリを学ばなくてはなりません。異なるレジスタが何を指しているかについては非常に混乱しています。誰かがesp、ebp、esiの違いを教えてください(非常に簡単に言えば)?

+0

EBP:http://stackoverflow.com/questions/579262/what-is-the-purpose-of-the-ebp-frame-pointer-register、ESPとEBP:http://stackoverflow.com/questions/5474355/why-does-leave-do-mov-esp-ebp-x86-assembly?rq = 1 –

答えて

7

spレジスタはスタックポインタで、pushおよびpopのようなスタック操作に使用されます。

スタックはLIFO構造(ラスト・イン・ファースト・アウト)として知られています。最後にプッシュされたものは、最初に出されたものです。これは、とりわけ、関数を呼び出す機能を実装するために使用されます。

bpレジスタは基本ポインタであり、スタックフレーム操作によく使用されます。

これは、特定のレベル(関数の実行中にspが変更されることがありますが、通常はそうではありません)では、ローカル変数、渡されたパラメータなどをスタック上に配置するための固定参照です。

次のようなアセンブリ言語で探している場合:

mov eax, [bp+8] 

あなたはコードアクセスにスタックレベル固有の変数を見ています。

siレジスタはソースインデックスであり、通常大量コピー操作(diはその同等の宛先インデックスです)に使用されます。インテルは、メモリ内のバイトを素早く動かすための具体的な命令とともにこれらのレジスタを持っていました。

e-は、これらの(元々の)16ビットレジスタの32ビットバージョンです。そして、十分でないかのように、私たちは64ビットのr-バリエーションも持っています:-)

おそらく最も簡単な開始場所はhereです。それは8086に特有ですが、コンセプトはあまり変わっていません。現在の作物と比較した8086のシンプルさは、あなたの教育の出発点になります。基本を学んだら、x86ファミリの後のメンバーに移動する方がはるかに簡単です。

ここに転記して、回答を自立させるためにかなり編集しました。


enter image description here

汎用

8086を登録し、CPUは8個の汎用レジスタを有し、各レジスタは、独自の名前を持つ:

  • AX - アキュムレータ・レジスタ(に分かれAH/AL)。おそらく一般的なもののための最も一般的に使用されるレジスタです。
  • BX - ベースアドレスレジスタ(BH/BLに分割)。
  • CX - カウントレジスタ(CH/CLに分割)。縄跳びとシフトのための特別な指示。
  • DX - データレジスタ(DH/DLに分割)。MULおよびDIV操作ではAXで、一部のポートではINおよびOUT操作を指定します。
  • SI - ソースインデックスレジスタ。これを大容量メモリ転送のソースとして使用する特別な目的の命令(DS:SI)。
  • DI - 宛先インデックスレジスタ。これを大容量メモリ転送の宛先として使用する特別な目的の命令(ES:DI)。
  • BP - 主にスタック上のパラメータと変数にアクセスするために使用されるベースポインタ。
  • - スタックポインタ。基本スタック操作に使用されます。

SEGMENT

  • CSを登録する - 現在の命令を含むセグメントでポイント。
  • DS - 一般に変数が定義されているセグメントを指します。
  • ES - 余分なセグメントレジスタは、その使用法を定義するためにコーダに任されています。
  • SS - スタックを含むセグメントをポイントします。

セグメントレジスタに任意のデータを格納することは可能ですが、これは決して良い考えではありません。セグメントレジスタは、アクセス可能なメモリブロックを指す非常に特殊な目的を持っています。

セグメントレジスタは汎用レジスタと一緒に動作し、任意のメモリ値にアクセスします。たとえば、物理アドレス12345hのメモリにアクセスする場合は、DS = 1230hSI = 0045hを設定できます。このようにして、16ビット値に制限された単一のレジスタを使用する場合よりもはるかに多くのメモリにアクセスできます。

1230 
0045 
===== 
12345 

2つのレジスタで形成されたアドレスが有効アドレスと呼ばれる。

CPUは10hによってセグメント・レジスタを乗算し、それを汎用レジスタ(1230h * 10h + 45h = 12345h)を添加することにより、物理アドレスの計算を行います。

この使用法は、リアルモード専用です(これは8086の唯一のモードです)。後のプロセッサはこれらのレジスタをセグメントからセレクタに変更し、固定された計算を実行するのではなく、テーブル内のアドレスを検索するために使用されます。

デフォルトでは、BX,SIおよびDIレジスタはDSセグメントレジスタで動作します。 BPおよびSPは、セグメントレジスタSSで動作します。

特別な目的は

IPレジスタ - 命令ポインタ:

  • は必ず実行すべき次の命令を指します。
  • CSを基準にしたオフセットアドレス。

IPレジスタは常にCSセグメントレジスタと一緒に動作し、現在実行中の命令を指しています。

FLAGS

レジスタ、プロセッサの現在の状態を判定する。これらのフラグは、数学演算後にCPUによって自動的に変更され、結果のタイプを判別し、制御をプログラムの他の部分に移す条件を決定することができます。

通常、これらのレジスタに直接アクセスすることはできません。

enter image description here

  • キャリーフラグCF - 符号なしオーバーフローがある場合に、このフラグが1に設定されています。たとえば、255 + 1バイトを加算すると(結果は0〜255の範囲に含まれません)。オーバーフローがない場合、このフラグは0に設定されます。
  • パリティフラグPF - このフラグは、結果に1ビットの偶数がある場合は1に設定され、1ビットの奇数の場合は0に設定されます。
  • 補助フラグAF - 低ニブル(4ビット)の符号なしオーバーフローがある場合に1に設定されます。
  • ゼロフラグZF - 結果がゼロの場合に1に設定されます。ゼロ以外の結果の場合、このフラグは0に設定されます。
  • 符号フラグSF - 結果が負のときに1に設定されます。結果が正のときは0に設定されます(このフラグは最上位ビットの値をとります)。
  • トラップフラグTF - オンチップデバッグに使用されます。
  • 割り込み許可フラグIF - このフラグを1に設定すると、CPUは外部デバイスからの割り込みに反応します。
  • 方向フラグDF - このフラグは、データチェーンを処理するためにいくつかの命令で使用されます。このフラグが0に設定されている場合は処理が順方向に行われ、このフラグが1に設定されている場合は処理が逆方向に行われます。
  • オーバーフローフラグOF - 符号付きオーバーフローが発生したときに1に設定されます。たとえば、100 + 50バイトを加算すると(結果は-128〜127の範囲内にありません)。
+0

これらのプレフィックスに 'e'と' r'を選択する根拠は何ですか? –

+2

@Tomalex:いいえ。おそらく 'e'は' extended 'を意味し、 'r'は' '本当に拡張された' :-)の意味です。 – paxdiablo

+0

8086には' ebp'、 'esp'、' esi'はありません。誰も8086について言及していません。なぜこれがここにありますか? – cHao

10

MIPSのようないくつかのアーキテクチャでは、すべてのレジスタが等しく作成されており、レジスタ名(およびソフトウェア規則)以外の違いはありません。 x86では、ほとんどの場合、汎用コンピューティング用の任意のレジスタを使用できますが、いくつかのレジスタは命令セットに暗黙的にバインドされています。

レジスタの特別な目的についての多くの情報はhereです。

例:

    eax
  • 、アキュムレータ:多くの算術命令暗黙eax上で動作します。多くの命令では、EAXに特化した特殊なエンコードもあります。たとえば、add eax, 123456は、add ecx, 123456より1バイト短くなります。(add eax, imm32 vs. add r/m32, imm32
  • ebx、ベース:暗黙的な使用はほとんどありませんが、xlatは "ベース"の命名に一致するものです。さらに関連性:cmpxchg8b。位置特定コード(PIC)の一部の32ビット呼び出し規約/ ABI use it as a pointer to the "global offset table"は、特定のものではめったに必要ないためです。
  • edx、データいくつかの算術演算は、暗黙edxに64ビット値で動作:eax
  • ecx、シフトカウントに使用カウンタ、rep movsため。また、mostly-obsolete loop instructionは暗黙のうちにecx
  • esi、ソースインデックスをデクリメント:いくつかの文字列操作がメモリから文字列を読み込んesiによって
  • ediを指摘し、宛先インデックス:いくつかの文字列操作はメモリに文字列を書き込むediで指されます。例えばrep movsbは、[esi]から[edi]までのECXバイトをコピーします。
  • ebp、ベースポインタ:通常はローカル変数を指すために使用されます。暗黙的にleaveによって使用されます。
  • esp、スタックポインタ:pushによって暗黙的に使用されるスタックの上部を指し、popcallret

x86命令セットは、実際、複雑な獣です。多くの命令には、暗黙的に1つのレジスタまたは別のものを使用する短い形式があります。特定のアドレス指定を行うために使用できるレジスタもあれば、使用できないレジスタもあります。

Intel 80386 Programmer's Reference Manualは、置き換えが不可能なリソースです。基本的には、最新のハードウェアの新しい拡張機能やパフォーマンスを除いて、x86アセンブリについて知っておくべきことがすべて分かります。

PC Assembly(e)本は、アセンブリを学習するための優れたリソースです。

+0

私はpaxdiabloがこれを書いている間に "少し"詳しい情報を含むように彼の答えを更新しましたが、私はリンクのためにここに残します。 :) –

+1

+1は正しいCPUを参照するためのものであり、他の情報の洪水で答えを失わないためです。 – cHao

+1

素敵な要約。 +1。もう一度ビジネスをするだろう。 –

1

ここでは簡単な要約です:

ESPは、現在のスタックポインタであるので、あなたは、一般的にのみスタックを操作するためにそれを更新し、EBPはあまりにもスタック操作のために意図され、例えばスタックスペースを割り当てる前にESPの値を保存するにはローカル変数の場合。しかし、EBPを汎用レジスタとして使用することもできます。

ESIは拡張ソースインデックスレジスタであり、MOVSのようなESIとEDIの命令は、 "文字列"(C文字列とは異なります。アドレッシング

メモリ:のx86 CPUは、「セグメント・レジスタ」と呼ばれるこれらの特殊レジスタを有する

、それらの各々は、異なるアドレスを指すことができ、例えば、(一般にデータ・セグメントと呼ばれる)DSは、0x1000000番地を指すこと、及びSS(一般スタックセグメントと呼ばれる)が0x2000000を指している可能性があります。

EBPとESPを使用する場合、デフォルトのセグメントレジスタはSSで、ESI(および他の汎用レジスタ)ではDSです。

mov eax,ds:[ebp] 
:デフォルトを上書きし、

mov eax,[esp] //loading from address 0x2000000 + 0x10 
    mov eax,[esi] //loading from address 0x1000000 + 0x10 

ます。また、使用するセグメントレジスタを指定することができます。たとえば、のは、DS = 0x1000000番地、SS = 0x2000000、EBP = 0x10を、ESI = 0x10を、そうは言ってみましょう

加算、減算、論理演算などに関しては、実際の違いはありません。

関連する問題