Share via


Menggunakan dan Mempertahankan Pendaftaran di Rakitan Sebaris

Khusus Microsoft

Secara umum, Anda tidak boleh berasumsi bahwa register akan memiliki nilai tertentu ketika __asm blok dimulai. Nilai register tidak dijamin akan dipertahankan di seluruh blok terpisah __asm . Jika Anda mengakhiri blok kode sebaris dan memulai yang lain, Anda tidak dapat mengandalkan register di blok kedua untuk mempertahankan nilainya dari blok pertama. Blok __asm mewarisi nilai register apa pun yang dihasilkan dari alur kontrol normal.

Jika Anda menggunakan __fastcall konvensi panggilan, pengkompilasi meneruskan argumen fungsi dalam register alih-alih pada tumpukan. Ini dapat membuat masalah dalam fungsi dengan __asm blok karena fungsi tidak memiliki cara untuk mengetahui parameter mana yang mendaftar. Jika fungsi kebetulan menerima parameter di EAX dan segera menyimpan sesuatu yang lain di EAX, parameter asli hilang. Selain itu, Anda harus mempertahankan register ECX dalam fungsi apa pun yang dideklarasikan dengan __fastcall.

Untuk menghindari konflik register tersebut __fastcall , jangan gunakan konvensi untuk fungsi yang berisi __asm blok. Jika Anda menentukan __fastcall konvensi secara global dengan opsi pengkompilasi /Gr, nyatakan setiap fungsi yang __asm berisi blok dengan __cdecl atau __stdcall. (Atribut __cdecl memberi tahu pengkompilasi untuk menggunakan konvensi panggilan C untuk fungsi tersebut.) Jika Anda tidak mengkompilasi dengan /Gr, hindari mendeklarasikan fungsi dengan __fastcall atribut .

Saat menggunakan __asm untuk menulis bahasa assembly dalam fungsi C/C++, Anda tidak perlu mempertahankan pendaftaran EAX, EBX, ECX, EDX, ESI, atau EDI. Misalnya, di POWER2. Contoh C dalam Fungsi Penulisan dengan Rakitan Sebaris, power2 fungsi tidak mempertahankan nilai dalam register EAX. Namun, menggunakan register ini akan memengaruhi kualitas kode karena alokator register tidak dapat menggunakannya untuk menyimpan nilai di seluruh __asm blok. Selain itu, dengan menggunakan EBX, ESI atau EDI dalam kode perakitan sebaris, Anda memaksa kompilator untuk menyimpan dan memulihkan register tersebut dalam prolog fungsi dan epilog.

Anda harus mempertahankan register lain yang Anda gunakan (seperti DS, SS, SP, BP, dan daftar bendera) untuk cakupan __asm blok. Anda harus mempertahankan register ESP dan EBP kecuali Anda memiliki beberapa alasan untuk mengubahnya (misalnya untuk beralih tumpukan). Lihat juga Mengoptimalkan Rakitan Sebaris.

Beberapa jenis SSE memerlukan perataan tumpukan delapan byte, memaksa pengkompilasi untuk memancarkan kode perataan tumpukan dinamis. Agar dapat mengakses variabel lokal dan parameter fungsi setelah perataan, pengkompilasi mempertahankan dua penunjuk bingkai. Jika compiler melakukan kelalaian pointer bingkai (FPO), kompilator akan menggunakan EBP dan ESP. Jika compiler tidak melakukan FPO, ia akan menggunakan EBX dan EBP. Untuk memastikan kode berjalan dengan benar, jangan ubah EBX dalam kode asm jika fungsi memerlukan perataan tumpukan dinamis karena dapat memodifikasi penunjuk bingkai. Pindahkan jenis selaras delapan byte dari fungsi, atau hindari menggunakan EBX.

Catatan

Jika kode rakitan sebaris Anda mengubah bendera arah menggunakan instruksi STD atau CLD, Anda harus memulihkan bendera ke nilai aslinya.

END Khusus Microsoft

Baca juga

Perakitan Sebaris