Bagikan melalui


Arsitektur x86

Prosesor Intel x86 menggunakan arsitektur komputer set instruksi kompleks (CISC), yang berarti ada sejumlah besar register tujuan khusus alih-alih sejumlah besar register tujuan umum. Ini juga berarti bahwa instruksi tujuan khusus yang kompleks akan mendominasi.

Prosesor x86 melacak warisannya setidaknya sejauh prosesor Intel 8080 8-bit. Banyak kekhasan dalam set instruksi x86 disebabkan oleh kompatibilitas mundur dengan prosesor tersebut (dan dengan varian Zilog Z-80-nya).

Microsoft Win32 menggunakan prosesor x86 dalam mode datar 32-bit. Dokumentasi ini hanya akan berfokus pada mode datar.

Register

Arsitektur x86 terdiri dari daftar bilangan bulat yang tidak memiliki hak istimewa berikut.

eax

Akumulator

ebx

Register dasar

ecx

Daftar penghitung

edx

Data register - dapat digunakan untuk akses port I/O dan fungsi aritmatika

Esi

Register indeks sumber

Edi

Daftar indeks tujuan

ebp

Register penunjuk dasar

Esp

Penunjuk tumpukan

Semua register bilangan bulat adalah 32 bit. Namun, banyak dari mereka memiliki subregister 16-bit atau 8-bit.

kapak

eax 16 bit rendah

Bx

Ebx 16 bit rendah

cx

Ekx 16 bit rendah

Dx

Edx 16 bit rendah

Si

Rendah 16 bit esi

di

16 bit rendah edi

Bp

Rendah 16 bit ebp

Sp

Rendah 16 bit esp

Al

8 bit rendah eax

Ah

8 bit teks tinggi

Bl

8 bit rendah ebx

Bh

Tinggi 8 bit bx

Cl

8 bit rendah ekx

Ch

Tinggi 8 bit cx

Dl

8 bit rendah edx

Dh

Tinggi 8 bit dx

Beroperasi pada sub-pendaftaran hanya memengaruhi subregister dan tidak ada bagian di luar sub-pendaftaran. Misalnya, menyimpan ke register kapak meninggalkan 16 bit tinggi dari register eax tidak berubah.

Saat menggunakan ? (Evaluasi Ekspresi) perintah, register harus diawali dengan tanda "at" ( @ ). Misalnya, Anda harus menggunakan ? @ax daripada ? ax. Ini memastikan bahwa debugger mengenali sumbu sebagai register daripada simbol.

Namun, (@) tidak diperlukan dalam perintah r (Registers ). Misalnya, r ax=5 akan selalu ditafsirkan dengan benar.

Dua register lainnya penting untuk status prosesor saat ini.

eip

penunjuk instruksi

flags

flags

Penunjuk instruksi adalah alamat instruksi yang dijalankan.

Register bendera adalah kumpulan bendera bit tunggal. Banyak instruksi mengubah bendera untuk menjelaskan hasil instruksi. Bendera-bendera ini kemudian dapat diuji dengan instruksi lompat bersyar. Lihat Bendera x86 untuk detailnya.

Konvensi Panggilan

Arsitektur x86 memiliki beberapa konvensi panggilan yang berbeda. Untungnya, mereka semua mengikuti aturan pelestarian register dan pengembalian fungsi yang sama:

  • Fungsi harus mempertahankan semua register, kecuali untuk eax, ecx, dan edx, yang dapat diubah di seluruh panggilan fungsi, dan esp, yang harus diperbarui sesuai dengan konvensi panggilan.

  • Register eax menerima nilai pengembalian fungsi jika hasilnya adalah 32 bit atau lebih kecil. Jika hasilnya adalah 64 bit, maka hasilnya disimpan dalam pasangan edx:eax .

Berikut ini adalah daftar konvensi panggilan yang digunakan pada arsitektur x86:

  • Win32 (__stdcall)

    Parameter fungsi diteruskan pada tumpukan, didorong kanan ke kiri, dan penerima panggilan membersihkan tumpukan.

  • Panggilan metode C++ asli (juga dikenal sebagai thiscall)

    Parameter fungsi diteruskan pada tumpukan, didorong kanan ke kiri, penunjuk "ini" diteruskan dalam register ecx , dan callee membersihkan tumpukan.

  • COM (__stdcall untuk panggilan metode C++)

    Parameter fungsi diteruskan pada tumpukan, didorong kanan ke kiri, lalu penunjuk "ini" didorong pada tumpukan, dan kemudian fungsi dipanggil. Penerima panggilan membersihkan tumpukan.

  • __fastcall

    Dua argumen DWORD-atau-smaller pertama diteruskan dalam ecx dan edx register. Parameter yang tersisa diteruskan pada tumpukan, didorong ke kanan ke kiri. Penerima panggilan membersihkan tumpukan.

  • __cdecl

    Parameter fungsi diteruskan pada tumpukan, didorong kanan ke kiri, dan pemanggil membersihkan tumpukan. Konvensi panggilan __cdecl digunakan untuk semua fungsi dengan parameter panjang variabel.

Tampilan Debugger Daftar dan Bendera

Berikut adalah contoh tampilan register debugger:

eax=00000000 ebx=008b6f00 ecx=01010101 edx=ffffffff esi=00000000 edi=00465000
eip=77f9d022 esp=05cffc48 ebp=05cffc54 iopl=0         nv up ei ng nz na po nc
cs=001b  ss=0023  ds=0023  es=0023  fs=0038  gs=0000             efl=00000286

Dalam penelusuran kesalahan mode pengguna, Anda dapat mengabaikan iopl dan seluruh baris terakhir tampilan debugger.

Bendera x86

Dalam contoh sebelumnya, kode dua huruf di akhir baris kedua adalah bendera. Ini adalah register bit tunggal dan memiliki berbagai kegunaan.

Tabel berikut mencantumkan bendera x86:

Kode Bendera Nama Bendera Nilai Status Bendera Deskripsi
Tengah Bendera Luapan 0 1 nvov Tidak ada luapan - Luapan
Df Bendera Arah 0 1 updn Arah ke atas - Arah ke bawah
if Bendera Interupsi 0 1 diei Interupsi dinonaktifkan - Interupsi diaktifkan
Sf Tanda tangani Bendera 0 1 plng Positif (atau nol) - Negatif
zf Bendera Nol 0 1 nzzr Nonzero - Nol
af Bendera Carry Tambahan 0 1 naac Tidak ada carry tambahan - Carry tambahan
Pf Bendera Paritas 0 1 pepo Parity odd - Parity even
Cf Bawa Bendera 0 1 nccy Tidak ada carry - Carry
tf Bendera Trap Jika tf sama dengan 1, prosesor akan menaikkan pengecualian STATUS_SINGLE_STEP setelah eksekusi satu instruksi. Bendera ini digunakan oleh debugger untuk menerapkan pelacakan langkah tunggal. Ini tidak boleh digunakan oleh aplikasi lain.
iopl Tingkat Hak Istimewa I/O Tingkat Hak Istimewa I/O Ini adalah bilangan bulat dua-bit, dengan nilai antara nol dan 3. Ini digunakan oleh sistem operasi untuk mengontrol akses ke perangkat keras. Ini tidak boleh digunakan oleh aplikasi.

Ketika register ditampilkan sebagai hasil dari beberapa perintah di jendela Perintah Debugger, itu adalah status bendera yang ditampilkan. Namun, jika Anda ingin mengubah bendera menggunakan perintah r (Registers), Anda harus merujuknya dengan kode bendera.

Di jendela Daftar WinDbg, kode bendera digunakan untuk melihat atau mengubah bendera. Status bendera tidak didukung.

Berikut adalah contohnya. Di tampilan register sebelumnya, status bendera ng muncul. Ini berarti bahwa bendera tanda saat ini diatur ke 1. Untuk mengubah ini, gunakan perintah berikut:

r sf=0

Ini mengatur bendera tanda ke nol. Jika Anda melakukan tampilan register lain, kode status ng tidak akan muncul. Sebagai gantinya , kode status pl akan ditampilkan.

Bendera Tanda, Bendera Nol, dan Bendera Carry adalah bendera yang paling umum digunakan.

Kondisi

Kondisi menjelaskan status satu atau beberapa bendera. Semua operasi kondisional pada x86 dinyatakan dalam hal kondisi.

Perakitan menggunakan singkatan satu atau dua huruf untuk mewakili kondisi. Kondisi dapat diwakili oleh beberapa singkatan. Misalnya, AE ("di atas atau sama") adalah kondisi yang sama dengan NB ("tidak di bawah"). Tabel berikut ini mencantumkan beberapa kondisi umum dan maknanya.

Nama Kondisi Bendera Makna

Z

ZF=1

Hasil operasi terakhir adalah nol.

NZ

ZF=0

Hasil operasi terakhir bukan nol.

C

CF=1

Operasi terakhir memerlukan carry atau pinjam. (Untuk bilangan bulat yang tidak ditandatangani, ini menunjukkan luapan.)

NC

CF=0

Operasi terakhir tidak memerlukan carry atau pinjam. (Untuk bilangan bulat yang tidak ditandatangani, ini menunjukkan luapan.)

S

SF=1

Hasil operasi terakhir memiliki set bit tinggi.

NS

SF=0

Hasil operasi terakhir memiliki bit tinggi yang jelas.

O

OF=1

Ketika diperlakukan sebagai operasi bilangan bulat yang ditandatangani, operasi terakhir menyebabkan luapan atau aliran bawah.

TIDAK

OF=0

Ketika diperlakukan sebagai operasi bilangan bulat yang ditandatangani, operasi terakhir tidak menyebabkan luapan atau aliran bawah.

Kondisi juga dapat digunakan untuk membandingkan dua nilai. Instruksi cmp membandingkan dua operannya, lalu mengatur bendera seolah-olah dikurangi satu operand dari yang lain. Kondisi berikut dapat digunakan untuk memeriksa hasil nilai cmp1, value2.

Nama Kondisi Bendera Artinya setelah operasi CMP.

E

ZF=1

value1 == value2.

NE

ZF=0

value1 != value2.

GE NL

SF=OF

value1>= value2. Nilai diperlakukan sebagai bilangan bulat yang ditandatangani.

LE NG

ZF=1 atau SF!=OF

value1<= value2. Nilai diperlakukan sebagai bilangan bulat yang ditandatangani.

G NLE

ZF=0 dan SF=OF

value1>value2. Nilai diperlakukan sebagai bilangan bulat yang ditandatangani.

L NGE

SF!=OF

value1<value2. Nilai diperlakukan sebagai bilangan bulat yang ditandatangani.

AE NB

CF=0

value1>= value2. Nilai diperlakukan sebagai bilangan bulat yang tidak ditandatangani.

BE NA

CF=1 atau ZF=1

value1<= value2. Nilai diperlakukan sebagai bilangan bulat yang tidak ditandatangani.

A NBE

CF=0 dan ZF=0

value1>value2. Nilai diperlakukan sebagai bilangan bulat yang tidak ditandatangani.

B NAE

CF=1

value1<value2. Nilai diperlakukan sebagai bilangan bulat yang tidak ditandatangani.

Kondisi biasanya digunakan untuk bertindak berdasarkan hasil instruksi cmp atau pengujian . Contohnya,

cmp eax, 5
jz equal

membandingkan register eax dengan angka 5 dengan menghitung ekspresi (eax - 5) dan mengatur bendera sesuai dengan hasilnya. Jika hasil pengurangan adalah nol, maka bendera zr akan diatur, dan kondisi jz akan benar sehingga lompatan akan diambil.

Tipe Data

  • byte: 8 bit

  • word: 16 bit

  • dword: 32 bit

  • qword: 64 bit (termasuk floating-point doubles)

  • tword: 80 bit (termasuk floating-point extended doubles)

  • oword: 128 bit

Notasi

Tabel berikut menunjukkan notasi yang digunakan untuk menjelaskan instruksi bahasa perakitan.

Notasi Makna

r, r1, r2...

Register

m

Alamat memori (lihat bagian Mode Alamat yang berhasil untuk informasi selengkapnya.)

#n

Konstanta langsung

r/m

Daftar atau memori

r/#n

Mendaftarkan atau konstanta langsung

r/m/#n

Mendaftarkan, memori, atau konstanta langsung

Cc

Kode kondisi yang tercantum di bagian Kondisi sebelumnya.

T

"B", "W", atau "D" (byte, word atau dword)

accT

Akumulator Ukuran T: al jika T = "B", ax jika T = "W", atau eax jika T = "D"

Mode Alamat

Ada beberapa mode alamat yang berbeda, tetapi semuanya mengambil formulir T ptr [expr], di mana T adalah beberapa jenis data (lihat bagian Jenis Data sebelumnya) dan expr adalah beberapa ekspresi yang melibatkan konstanta dan register.

Notasi untuk sebagian besar mode dapat disimpulkan tanpa banyak kesulitan. Misalnya, BYTE PTR [esi+edx*8+3] berarti "ambil nilai esi register, tambahkan delapan kali nilai register edx , tambahkan tiga, lalu akses byte pada alamat yang dihasilkan."

Pipelining

Pentium adalah masalah ganda, yang berarti dapat melakukan hingga dua tindakan dalam satu jam centang. Namun, aturan tentang kapan ia mampu melakukan dua tindakan sekaligus (dikenal sebagai pemasangan) sangat rumit.

Karena x86 adalah prosesor CISC, Anda tidak perlu khawatir tentang slot penundaan lompat.

Akses Memori yang Disinkronkan

Instruksi pemuatan, modifikasi, dan penyimpanan dapat menerima awalan kunci , yang memodifikasi instruksi sebagai berikut:

  1. Sebelum mengeluarkan instruksi, CPU akan menghapus semua operasi memori yang tertunda untuk memastikan koherensi. Semua prefetch data ditinggalkan.

  2. Saat mengeluarkan instruksi, CPU akan memiliki akses eksklusif ke bus. Ini memastikan atomitas operasi pemuatan/modifikasi/penyimpanan.

Instruksi xchg secara otomatis mematuhi aturan sebelumnya setiap kali bertukar nilai dengan memori.

Semua instruksi lainnya default ke nonlocking.

Prediksi Lompat

Lompatan tanpa syarat diprediksi akan diambil.

Lompatan kondisional diprediksi diambil atau tidak, tergantung pada apakah mereka diambil terakhir kali dieksekusi. Cache untuk merekam riwayat lompatan berukuran terbatas.

Jika CPU tidak memiliki catatan apakah lompatan bersyarkat diambil atau tidak diambil saat terakhir kali dijalankan, CPU memprediksi lompatan berskalakan mundur seperti yang diambil dan meneruskan lompatan bersyar seperti yang tidak diambil.

Alignment

Prosesor x86 akan secara otomatis memperbaiki akses memori yang tidak ditandatangani, dengan penalti performa. Tidak ada pengecualian yang dimunculkan.

Akses memori dianggap selaras jika alamat adalah bilangan bulat kelipatan ukuran objek. Misalnya, semua akses BYTE diselaraskan (semuanya adalah bilangan bulat kelipatan 1), akses WORD ke alamat genap selaras, dan alamat DWORD harus kelipatan 4 agar selaras.

Awalan kunci tidak boleh digunakan untuk akses memori yang tidak ditandatangani.