ESIおよびEDIレジスタの目的は?


回答:


77

DI / SIでしか実行できない操作がいくつかあります(1985年にASMを習得していなかった場合は、対応する拡張機能)。これらの中には

REP STOSB
REP MOVSB
REP SCASB

それぞれ、繰り返し(=大量に)保存、読み込み、スキャンする操作です。あなたがすることは、あなたが一方または両方のオペランドを指すようにSIおよび/またはDIを設定し、おそらくCXにカウントを入れてから、リッピングさせます。これらは一度に大量のバイトを処理する操作であり、一種のCPUを自動化します。ループを明示的にコーディングしていないため、手作業でコーディングしたループよりも(通常は)ループの方が効率的です。

念のために:オペレーションの設定方法によっては、値0を連続した大きなメモリブロックにパンチするなど、繰り返し格納するのが簡単な場合があります。MOVSBは、あるバッファー(バイトの束)から別のバッファーにデータをコピーするために使用されていると思います。そしてSCASBは、ある検索基準に一致するバイトを探すために使用されます(それが等しいか、何を検索しているだけなのかわかりません。検索できます:))

これが、これらのregの目的のほとんどです。


7
過去の最適化のヒント:rep stoswrep stosbよりもはるかに高速であるため、2バイトと2バイトをコピーすることが目的に適合している場合は、手動で最適化された16ビットx86アセンブリコードで代わりにそれを使用してください...
アレクサンダー

88

SI=ソースインデックス
DI=デスティネーションインデックス

他の人が示したように、文字列命令には特別な使用法があります。リアルモードのプログラミングについては、ESセグメントレジスタを一緒に使用しなければならないDIDSしてSIのように

movsb  es:di, ds:si

SIおよびDIは、汎用インデックスレジスタとしても使用できます。たとえば、Cソースコード

srcp [srcidx++] = argv [j];

コンパイルする

8B550C         mov    edx,[ebp+0C]
8B0C9A         mov    ecx,[edx+4*ebx]
894CBDAC       mov    [ebp+4*edi-54],ecx
47             inc    edi

whereにebp+12argvebxis 、 is j、およびedihas が含まれますsrcidx。3番目の命令はedi4で乗算さebpれ、0x54(の位置srcp)でオフセットが追加されることに注意してください。アドレスを囲む角括弧は間接参照を示します。


私はそれを見たところ、私は覚えていないことができますが、けれども、この確認は、ほとんどそれの、及びこの他の(スライド17)。

AX=アキュムレータ
DX=ダブルワードアキュムレータ
CX=カウンタ
BX=ベースレジスタ

それらは汎用レジスターのように見えますが、(予期せずに)それらの1つを使用する命令がいくつかありますが、暗黙のうちにどれを使用するかはわかりません。


37

ESIが指すメモリからEDIが指すメモリにデータを効率的にコピーするMOVSBやMOVSWのようなオペコード。したがって、

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!

12

他の回答で述べられている文字列操作(MOVS / INS / STOS / CMPS / SCASB / W / D / Qなど)に加えて、暗黙的に最小EDI / RDI:

SSE2 MASKMOVDQU(および今後のAVX VMASKMOVDQU)命令は、バイトをXMMレジスタからEDI / RDIが指すメモリに選択的に書き込みます。


6

一括操作に使用されるレジスタに加えて、32ビットの呼び出し規約で関数呼び出し(call-preserved)を通じて保持されるという特性に役立ちます。ESI、EDI、EBX、EBP、ESPはコール保持されますが、EAX、ECX、およびEDXはコール保持されません。呼び出し保存レジスタはCライブラリ関数によって尊重され、それらの値はCライブラリ関数呼び出しを通じて保持されます。

Jeff Duntemannは、アセンブリ言語の本で、コマンドライン引数を出力するためのサンプルアセンブリコードを持っています。これらのコードは、Cライブラリ関数printfによって変更されないため、esiおよびediを使用してカウンターを格納します。eax、ecx、edxなどの他のレジスタについては、Cライブラリ関数で使用されないという保証はありません。

https://www.amazon.com/Assembly-Language-Step-Step-Programming/dp/0470497025

See section 12.8 Cがコマンドライン引数をどう見るか。

64ビットの呼び出し規約は32ビットの呼び出し規約とは異なり、これらのレジスタが呼び出し保存されているかどうかはわかりません。


ほとんどの人が「揮発性」/「非揮発性」と呼んでいるものを説明するために使用される「神聖な」、または「呼び出し先保存」と「呼び出し元保存」のどちらも聞いたことがありません。「call-preserved」/「call-clobbered」が好きです。実際にどこかに保存されるわけではないからです。とにかく、ESI / RSIとEDI / RDIは、x86-64 System V ABIではコール保存されません。
Peter Cordes

また、EBPおよびESPを、一般的な32ビットの呼び出し規約で保存されている呼び出しとしてリストするのを忘れていました。
Peter Cordes

1
とにかく、それはかなり良い点です。実際のコードでは、呼び出し規約の理由に基づいて、EDI / ESIを選択する可能性が高くなります。これは、命令に対して特別であるからではありません。
Peter Cordes

プリザーブドコールが好きです。同じように答えを更新しました。レビューありがとうございます。
Jay Rajput
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.