Tujuan register ESI & EDI?

119

Apa tujuan sebenarnya dan penggunaan register EDI & ESI di assembler?

Saya tahu mereka digunakan untuk operasi string untuk satu hal.

Bisakah seseorang juga memberi contoh?

Tony The Lion
sumber
9
Lihat ini: swansontec.com/sregisters.html
Jeffpowrs

Jawaban:

77

Ada beberapa operasi yang hanya dapat Anda lakukan dengan DI / SI (atau rekannya yang diperluas, jika Anda tidak mempelajari ASM pada tahun 1985). Diantaranya adalah

REP STOSB
REP MOVSB
REP SCASB

Yaitu, operasi untuk penyimpanan, pemuatan, dan pemindaian berulang (= massal). Apa yang Anda lakukan adalah mengatur SI dan / atau DI untuk menunjuk ke salah satu atau kedua operan, mungkin menghitung di CX dan kemudian mari kita rip. Ini adalah operasi yang bekerja pada sekumpulan byte pada satu waktu, dan mereka semacam menempatkan CPU secara otomatis. Karena Anda tidak secara eksplisit mengkodekan loop, mereka melakukan tugasnya dengan lebih efisien (biasanya) daripada loop berkode tangan.

Untuk berjaga-jaga jika Anda bertanya-tanya: Bergantung pada bagaimana Anda mengatur operasi, penyimpanan berulang dapat menjadi sesuatu yang sederhana seperti memasukkan nilai 0 ke dalam blok memori yang berdekatan; MOVSB ​​digunakan, menurut saya, untuk menyalin data dari satu buffer (yah, sekumpulan byte) ke buffer lainnya; dan SCASB digunakan untuk mencari byte yang cocok dengan beberapa kriteria pencarian (Saya tidak yakin apakah itu hanya mencari persamaan, atau apa - Anda dapat mencarinya :))

Itulah sebagian besar dari tujuan reg itu.

Carl Smotricz
sumber
7
Tip pengoptimalan dari masa lalu: rep stosw jauh lebih cepat daripada rep stosb , jadi jika menyalin dua dan dua byte sesuai dengan apa yang Anda coba lakukan, gunakan itu sebagai gantinya dalam kode assembly 16-bit x86 yang dioptimalkan secara manual ...
Alexander
88

SI= Indeks Sumber
DI= Indeks Tujuan

Seperti yang ditunjukkan orang lain, mereka memiliki kegunaan khusus dengan instruksi string. Untuk pemrograman mode real, ESregister segmen harus digunakan dengan DIdan DSdengan SIas in

movsb  es:di, ds:si

SI dan DI juga dapat digunakan sebagai register indeks tujuan umum. Misalnya Ckode sumber

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

dikompilasi menjadi

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

where ebp+12contains argv, ebxis j, dan edihas srcidx. Perhatikan instruksi ketiga menggunakan edimulitplied dengan 4 dan menambahkan ebpoffset dengan 0x54 (lokasi srcp); tanda kurung di sekitar alamat menunjukkan tipu muslihat.


Meskipun saya tidak dapat mengingat di mana saya melihatnya, tetapi ini menegaskan sebagian besar, dan ini (slide 17) lainnya:

AX= akumulator = akumulator
DXkata ganda
CX= counter
BX= basis register

Mereka terlihat seperti register tujuan umum, tetapi ada sejumlah instruksi yang (secara tidak terduga?) Menggunakan salah satunya — tetapi yang mana? — Secara implisit.

wallyk
sumber
37

Opcode seperti MOVSB ​​dan MOVSW yang secara efisien menyalin data dari memori yang ditunjukkan oleh ESI ke memori yang ditunjuk oleh EDI. Jadi,

mov esi, source_address
mov edi, destination_address
mov ecx, byte_count
cld
rep movsb ; fast!
makanan kucing
sumber
12

Selain operasi string (MOVS / INS / STOS / CMPS / SCASB / W / D / Q dll.) Yang disebutkan dalam jawaban lain, saya ingin menambahkan bahwa ada juga instruksi perakitan x86 yang lebih "modern" yang secara implisit digunakan di setidaknya EDI / RDI:

Instruksi SSE2 MASKMOVDQU(dan AVX yang akan datang VMASKMOVDQU) secara selektif menulis byte dari register XMM ke memori yang ditunjukkan oleh EDI / RDI.

PhiS
sumber
6

Selain register yang digunakan untuk operasi massal, register berguna karena propertinya dipertahankan melalui pemanggilan fungsi (call-preserved) dalam konvensi pemanggilan 32-bit. ESI, EDI, EBX, EBP, ESP dipertahankan panggilan sedangkan EAX, ECX dan EDX tidak dipertahankan panggilan. Register yang dipertahankan dengan panggilan dipatuhi oleh fungsi perpustakaan C dan nilainya tetap ada melalui panggilan fungsi perpustakaan C.

Jeff Duntemann dalam buku bahasa assembly-nya memiliki contoh kode assembly untuk mencetak argumen baris perintah. Kode menggunakan esi dan edi untuk menyimpan penghitung karena mereka tidak akan diubah oleh printf fungsi perpustakaan C. Untuk register lain seperti eax, ecx, edx, tidak ada jaminan tidak akan digunakan oleh fungsi perpustakaan C.

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

Lihat bagian 12.8 Bagaimana C melihat Argumen Baris Perintah.

Perhatikan bahwa konvensi panggilan 64-bit berbeda dari konvensi panggilan 32-bit, dan saya tidak yakin apakah register ini dipertahankan panggilan atau tidak.

Jay Rajput
sumber
Saya belum pernah mendengar "sakral" digunakan untuk menggambarkan apa yang kebanyakan orang sebut "volatile" / "non-volatile", atau "callee-saving" vs "caller-saving". Saya suka "panggilan-dipertahankan" / "panggilan-clobbered", karena tidak berarti bahwa mereka benar-benar disimpan di mana pun. Bagaimanapun, ESI / RSI dan EDI / RDI tidak disimpan dalam panggilan di x86-64 System V ABI.
Peter Cordes
Selain itu, Anda lupa mencantumkan EBP dan ESP sebagai panggilan yang dipertahankan dalam konvensi panggilan 32-bit yang umum.
Peter Cordes
1
Bagaimanapun, itu poin yang cukup bagus. Dalam kode sebenarnya, Anda lebih cenderung memilih EDI / ESI untuk sesuatu yang didasarkan pada alasan konvensi panggilan daripada karena alasan tersebut khusus untuk instruksi apa pun.
Peter Cordes
Saya suka panggilan dipertahankan. Saya telah memperbarui jawabannya dengan yang sama. Terima kasih atas reviewnya.
Jay Rajput