Bagikan melalui


Arsitektur x86

Prosesor Intel x86 menggunakan arsitektur komputer set instruksi kompleks (CISC), yang berarti ada sejumlah register tujuan khusus yang terbatas alih-alih sejumlah register tujuan umum dalam jumlah besar. 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

Register 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.

sumbu

16 bit rendah eax

bx

16 bit rendah ebx

cx

16 bit rendah dari ecx

dx

16 bit rendah dari edx

si

16 bit rendah esi

di

16 bit rendah edi

bp

16 bit rendah ebp

sp

16 bit rendah esp

al

Bit rendah ke-8 dari eax

ah

8 bit paling signifikan dari ax

bl

8 bit rendah dari ebx

bh

8 bit teratas dari bx

cl

8 bit rendah ecx

ch

Bit ke-8 paling tinggi dari cx

dl

8 bit rendah edx

dh

Delapan bit tertinggi dari dx

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

Saat menggunakan perintah ? (Evaluasi Ekspresi), register harus diawali dengan tanda "at" ( @ ). Misalnya, Anda harus menggunakan ? @ax daripada ? ax. Ini memastikan bahwa debugger mengenali ax 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

bendera

Bendera

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 bersyarat. 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 selama 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 di ecx mendaftar, dan penerima panggilan 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. Callee membersihkan stack.

  • __fastcall

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

  • __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 Register dan Penanda

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 debugging 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 Etik Bendera Nama Bendera Nilai Status Bendera Deskripsi
dari Bendera Luapan 0 1 nvov Tidak ada luapan - Luapan
df Bendera Arah 0 1 updn Arah ke atas - Arah ke bawah
jika Bendera Pemutusan 0 1 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 (Mengindikasikan Paritas) 0 1 pepo Paritas ganjil - Paritas genap
cf Bawa Bendera 0 1 nccy Tidak ada carry - Carry
tf Bendera Jebakan 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, yang ditampilkan adalah status flag . Namun, jika Anda ingin mengubah flag menggunakan perintah r (Registers) , Anda harus mengacu pada kode flag .

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 Arti

Z

ZF=1

Hasil operasi terakhir adalah nol.

NZ

ZF=0

Hasil operasi terakhir bukan nol.

C

CF=1

Operasi terakhir memerlukan bawa atau pinjaman. (Untuk integer tanpa tanda, ini menunjukkan kelebihan kapasitas.)

NC

CF=0

Operasi terakhir tidak memerlukan pengangkatan atau peminjaman. (Untuk integer tanpa tanda, ini menunjukkan kelebihan kapasitas.)

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 operan dari yang lain. Kondisi berikut dapat digunakan untuk memeriksa hasil cmpvalue1, value2.

Nama Kondisi Bendera Artinya setelah operasi CMP.

E

ZF=1

nilai1 == nilai2.

NE

ZF=0

nilai 1 != nilai 2.

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

nilai1>nilai2. Nilai diperlakukan sebagai bilangan bulat yang ditandatangani.

L NGE

SF!=OF

nilai1<nilai2. 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

nilai1>nilai2. Nilai diperlakukan sebagai bilangan bulat yang tidak ditandatangani.

B NAE

CF=1

nilai1<nilai2. Nilai diperlakukan sebagai bilangan bulat yang tidak ditandatangani.

Kondisi umumnya digunakan untuk bertindak berdasarkan hasil dari instruksi cmp atau pengujian . Misalnya

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 Arti

r, r1, r2...

Register

m

Alamat memori (lihat bagian Mode Alamat yang berikutnya 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

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

Mode Pengalamatan

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 daftar.

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

Pipelining

Pentium adalah prosesor dengan kemampuan dual-issue, yang berarti dapat melakukan hingga dua tindakan dalam satu siklus clock. Namun, aturan tentang kapan sistem tersebut 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 memuat, memodifikasi, dan menyimpan dapat menerima prefiks kunci , yang memodifikasi instruksi sebagai berikut:

  1. Sebelum mengeluarkan instruksi, CPU akan menghapus semua operasi memori yang tertunda untuk memastikan koherensi. Semua permintaan awal data dibatalkan.

  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 secara default berstatus non-locking.

Prediksi Lompatan

Lompatan tanpa syarat diprediksi akan diambil.

Lompatan kondisional diprediksi akan diambil atau tidak, tergantung pada apakah lompatan tersebut diambil pada eksekusi sebelumnya. Cache untuk merekam riwayat lompatan berukuran terbatas.

Jika CPU tidak memiliki catatan apakah lompatan bersyarat diambil atau tidak diambil saat terakhir kali dijalankan, CPU memprediksi lompatan bersyarat mundur sebagai diambil dan lompatan bersyarat maju sebagai tidak diambil.

Alignment

Prosesor x86 akan secara otomatis memperbaiki akses memori yang tidak selaras, dengan penurunan performa. Tidak ada pengecualian yang terjadi.

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.

Prefiks pengunci sebaiknya tidak digunakan untuk akses memori yang tidak sejajar.

Lihat juga

Arsitektur x64

X86-64 Wikipedia