2009-12-06 25 views
90

ESI &アセンブラのESIレジスタの実際の目的と用途は何ですか?ESIおよびEDIレジスタの目的は?

私はそれらが文字列演算に使用されていることは分かっています。

例を挙げることができますか?

+6

これをチェックしてください:http://www.swansontec.com/sregisters.html – Jeffpowrs

答えて

62

はDI/SI(または1985年にASMを習得しなかった場合は拡張カウンターパート)としか操作できません。これらの中には、反復(=質量)保存、ローディングおよびスキャンのための操作である。あなたは、SIとDIのどちらか一方または両方のオペランドを指すように設定しています。おそらくCXにカウントを入れてからリッピングします。これらは、一度にたくさんのバイトで動作する操作であり、CPUを自動で実行します。ループを明示的にコーディングしているわけではないので、ハンドコーディングされたループよりも効率的に(通常は)処理します。

あなたが疑問に思っている場合:操作をどのように設定するかによって、重複するメモリブロックに値0をパンチするなどの単純な処理が可能です。 MOVSBは、1つのバッファ(ある種のバイト群)から別のバッファにデータをコピーするために使用されます。 SCASBはいくつかの検索条件に一致するバイトを検索するために使用されます(これは同等かどうかを調べるだけなのか、それともそれを探すことができるのですか?)

これはほとんどのものです。

+5

過去の最適化のヒント:* rep stosw *はrep stosb *よりも高速ですので、2バイトと2バイトをコピーすると何をしようとしているのですか?手作業で最適化された16ビットx86アセンブリコードの代わりにそれを使用してください... – Alexander

27

ESIが指すメモリからEDIが指すメモリにデータを効率的にコピーするMOVSBやMOVSWのようなオペコード。このように、文字列操作に加えて

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

は(MOVS/INS/STOS/CMPS/SCASB/W/D/Qなど)他の回答で述べたように、私はそこにあることを追加したい」また、より多くの暗黙のうち少なくともEDI/RDIを使用して、現代の」x86のアセンブリ命令:

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

63

SI =ソースインデックス
DI =宛先インデックス

他の人が示されているとおり、彼らはストリング命令と特別な用途があります。

movsb es:di, ds:si 

にSIとDIは、汎用インデックスレジスタとしても使用することができるようにリアルモードのプログラミングに、ESセグメントレジスタはSIDIDSと一緒に使用されなければなりません。例えば、Cソースコード

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

ebp+12argvを含ん

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

にコンパイルし、ebxjであり、そしてedisrcidxを有しています。3番目の命令では、ediが4で乗算され、ebpは0x54(位置はsrcp)で加算されます。アドレスの括弧は間接を示します。


私はそれを見たところ、私が覚えていることはできませんが 、しかし thisはそれのほとんどを確認し、 this(スライド17)その他:

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

これらは汎用レジスタのように見えますが、それらのうちの1つを(予期せぬことに)使用するが、どちらがどちらかを暗黙のうちに使用する。

3

大量演算に使用されるレジスタに加えて、レジスタは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

Cは、コマンドライン引数を見てどのように節12.8を参照してください。

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

+0

ほとんどの人が「揮発性」/「不揮発性」と呼んでいるものを記述するのに "神聖な" 、または "callee-saved"と "caller-saved"を比較します。彼らは実際にどこにでも救われることを意味するものではないので、私は "通話保存"/"コールクローバー"を好む。とにかく、ESI/RSIとEDI/RDIは、x86-64 System V ABIではコール・プリザーブされていません。 –

+0

また、共通の32ビット呼び出し規約では、EBPとESPを通話保留としてリストすることを忘れてしまいました。 –

+1

とにかく、それはかなり良い点です。実際のコードでは、呼び出し規約に基づいて何らかの理由でEDI/ESIを選択する可能性が高くなります。 –

関連する問題