Megosztás a következőn keresztül:


x86 architektúra

Az Intel x86 processzor összetett utasításkészletes számítógép -architektúrát (CISC) használ, ami azt jelenti, hogy a nagy mennyiségű általános célú regiszter helyett szerény számú speciális célú regiszter található. Ez azt is jelenti, hogy az összetett speciális célú utasítások dominálnak.

Az x86-os processzor legalább a 8 bites Intel 8080 processzorig visszavezeti az örökségét. Az x86 utasításkészlet számos sajátossága a processzorral (és annak Zilog Z-80-variánsával) való visszamenőleges kompatibilitásnak köszönhető.

A Microsoft Win32 az x86 processzort használja 32 bites lapos módban. Ez a dokumentáció csak a sík módra összpontosít.

Regiszterek

Az x86 architektúra a következő nem privilegizált egész szám regisztereket tartalmazza.

eax

Akkumulátor

ebx

Alapregisztrálás

ecx

Számláló regiszter

edx

Adatregisztrálás – I/O-porthozzáféréshez és számtani függvényekhez használható

esi

Forrásindex-regiszter

edi

Célindex-regiszter

ebp

Alapmutató-regiszter

esp

Veremmutató

Az összes egész számregisztrátor 32 bites. Sokuk azonban 16 bites vagy 8 bites alregisztráterekkel rendelkezik.

tengely

Alacsony 16 bites eax (egy regiszter)

bx

A ebx 16 alacsony bitje

cx

Az ecx alacsony 16 bites része

dx

Az edx alacsony 16 bitje

si

Alacsony 16 bites esi

di

Az alacsony 16 bites edi

bp

Alacsony 16 bites ebp

sp

16 bites alacsony esp

al

Alacsony 8 bites eax

ah

Nagy 8 bites tengely

bl

Alacsony 8 bites ebx

bh

Felső 8 bit bx

cl

Alacsony 8 bites ecx

ch

Legfelső 8 bitjei cx

dl

Az edx alacsony 8 bitje

dh

Felső 8 bites dx

Az alregiszteren való műveletvégzés csak az alregisztert érinti, és semmilyen részt az alregiszteren kívül. Például, ha a ax regiszterbe tárolunk, a eax nagy 16 bitje változatlan marad.

Amikor a ? (Kifejezés kiértékelése) parancsot használja, a regisztereket előtaggal kell ellátni "@' jellel (@). Például kell használnia? @axhelyett? ax. Ez biztosítja, hogy a hibakereső tengely ne szimbólumként, hanem regiszterként felismerje.

A (@) azonban nem kötelező az r (Regisztrálás) parancsban. Például az r ax=5 mindig helyesen lesz értelmezve.

A processzor aktuális állapota szempontjából két másik regiszter is fontos.

eip

utasításmutató

zászlók

Zászlók

Az utasításmutató a végrehajtás alatt álló utasítás címe.

A jelzőregiszter egybites jelzők gyűjteménye. Számos utasítás módosítja a jelzőket az utasítás eredményének leírásához. Ezek a jelzők ezután feltételes ugrási utasítások segítségével tesztelhetők. Részletekért lásd x86-zászlók.

Hívási konvenciók

Az x86 architektúra számos különböző hívási konvencióval rendelkezik. Szerencsére mind ugyanazokat a nyilvántartásmegőrzési és függvény-visszatérési szabályokat követik:

  • A függvényeknek meg kell őrizniük az összes regisztert, kivéve eax, ecxés edx, amelyek a függvényhívások során módosíthatók, és esp, amelyeket a hívó konvenciónak megfelelően kell frissíteni.

  • Az eax regiszter függvény-visszaadási értékeket kap, ha az eredmény 32 bites vagy kisebb. Ha az eredmény 64 bites, akkor az eredmény az edx:eax párban lesz tárolva.

Az alábbi lista az x86-os architektúrában használt hívási konvenciók listáját tartalmazza:

  • Win32 (__stdcall)

    A függvényparaméterek a verembe kerülnek, jobbról balra tolva, és a hívott tisztítja meg a vermet.

  • Natív C++ metódushívás (más néven thiscall)

    A függvényparaméterek a verembe kerülnek átadásra, balról jobbra tolva, a "this" mutató az ecx regiszterben kerül átadásra, és a hívott megtisztítja a vermet.

  • COM (__stdcall C++ metódushívásokhoz)

    A függvényparamétereket a veremre tolják, jobbról balra, majd a "this" mutatót tolják a veremre, és végül meghívják a függvényt. A hívó megtisztítja a vermet.

  • __fastcall

    Az első két DWORD vagy kisebb argumentumot az ecx és edx regiszterekbe továbbítják. A fennmaradó paraméterek a veremen lesznek átadva, jobbról balra leküldve. A hívott megtisztítja a veremet.

  • __cdecl

    A függvényparaméterek a veremre kerülnek, jobbról balra tolva, a hívó pedig törli a vermet. A __cdecl hívási konvenció változó hosszúságú paraméterekkel rendelkező összes függvényhez használható.

Hibakereső – Regiszterek és jelzők megjelenítése

Íme egy minta hibakereső regiszter kijelzés:

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

Felhasználói módú hibakeresés esetén figyelmen kívül hagyhatja a iopl- és a hibakereső megjelenítés teljes utolsó sorát.

x86-jelzők

Az előző példában a második sor végén lévő kétbetűs kódok zászlók. Ezek egybites regiszterek, és számos felhasználási módjuk van.

Az alábbi táblázat az x86-jelölőket sorolja fel:

Zászló Kódexe Jelző neve Érték Zászló állapota Leírás
Túlcsordulás jelző 0 1 nvov Nincs túlcsordulás – Túlcsordulás
df Irányjelző 0 1 updn Irány felfelé – Irány lefelé
ha Megszakításjelző 0 1 diei A megszakítások le vannak tiltva – A megszakítások engedélyezve vannak
sf Jelzőzászló 0 1 plng Pozitív (vagy nulla) – Negatív
zf Nulla jelzés 0 1 nzzr Nonzero - Nulla
af Kiegészítő átvitel jelzője 0 1 naac Nincs kiegészítő hordozás – Kiegészítő hordozás
pf Paritásjelző 0 1 pepo Paritás páratlan - Paritás páros
cf Átvivő jelző 0 1 titkos Nincs hordozás – Hordozás
tf Trap Flag Ha tf értéke 1, a processzor egy utasítás végrehajtása után STATUS_SINGLE_STEP kivételt fog eredményezni. Ezt a jelzőt egy hibakereső használja az egylépéses nyomkövetés implementálásához. Más alkalmazások nem használhatják.
iopl I/O jogosultsági szint I/O jogosultsági szint Ez egy kétbites egész szám, nulla és 3 közötti értékekkel. Az operációs rendszer a hardverhez való hozzáférés szabályozására használja. Nem szabad, hogy az alkalmazások használják.

Ha a regiszterek valamilyen parancs eredményeként jelennek meg a Hibakereső parancs ablakban, az jelző állapota jelenik meg. Ha azonban az r (Regisztrálás) paranccsal szeretne módosítani egy jelölőt, akkor a jelzőkódkell hivatkoznia rá.

A WinDbg Regisztrálás ablakában a jelzőkód a jelölők megtekintésére vagy módosítására szolgál. A zászló állapota nem támogatott.

Íme egy példa. A korábbi regiszter megjelenítőben a jelző zászló állapota ng látható. Ez azt jelenti, hogy a jelző jelenleg 1-re van állítva. Ennek módosításához használja a következő parancsot:

r sf=0

Ezzel nullára állítja a jelző bitet. Ha újabb regiszter megjelenítést végez, a ng állapotkód nem fog megjelenni. Ehelyett a pl állapotkód jelenik meg.

A leggyakrabban használt jelzők a sign Flag, a Zero Flag és a Carry Flag.

Feltételek

Egy feltétel egy vagy több jelölő állapotát írja le. Az x86 összes feltételes művelete feltételekben van kifejezve.

Az összeszerelő egy vagy két betűs rövidítéssel jelöl egy feltételt. Egy feltételt több rövidítés is jelölhet. Például az AE ("fenti vagy egyenlő") ugyanaz a feltétel, mint az NB ("nem alább"). Az alábbi táblázat felsorol néhány gyakori feltételt és azok jelentését.

Feltétel neve Zászlók Értelem

Z

ZF=1

Az utolsó művelet eredménye nulla volt.

NZ

ZF=0

Az utolsó művelet eredménye nem nulla volt.

C

CF=1

A legutóbbi művelethez átvitelre vagy kölcsönvételre volt szükség. (Aláíratlan egész számok esetén ez túlcsordulást jelez.)

NC

CF=0

A legutóbbi művelethez nem volt szükség átvitelre vagy kölcsönvételre. (Aláíratlan egész számok esetén ez túlcsordulást jelez.)

S

SF=1

Az utolsó művelet eredménye nagy bitkészlettel rendelkezik.

NS

SF=0

Az utolsó művelet eredménye tiszta magas helyiértékű bittel rendelkezik.

O

OF=1

Aláírt egész szám műveletként kezelve az utolsó művelet túlcsordulást vagy alulcsordulást okozott.

NEM

OF=0

Aláírt egész szám műveletként kezelve az utolsó művelet nem okozott túlcsordulást vagy alulcsordulást.

A feltételek két érték összehasonlítására is használhatók. A cmp utasítás összehasonlítja a két operandusát, majd úgy állítja be a jelölőket, mintha kivonták volna az egyik operandust a másikból. Az alábbi feltételek segítségével ellenőrizheti cmpérték1, érték2eredményét .

Feltétel megnevezése Zászlók Ez azt jelenti, hogy egy CMP-művelet után.

E

ZF=1

value1 == value2.

NE

ZF=0

érték1 != érték2.

GE NL

SF=OF

érték1>= érték2. Az értékek aláírt egész számokként vannak kezelve.

LE NG

ZF=1 vagy SF!=OF

érték1<= érték2. Az értékek aláírt egész számokként vannak kezelve.

G NLE

ZF=0 és SF=OF

value1>value2. Az értékek aláírt egész számokként vannak kezelve.

L NGE

SF!=OF

value1<value2. Az értékek aláírt egész számokként vannak kezelve.

AE NB

CF=0

érték1>= érték2. Az értékeket a rendszer aláíratlan egész számként kezeli.

BE NA

CF=1 vagy ZF=1

érték1<= érték2. Az értékeket a rendszer aláíratlan egész számként kezeli.

A NBE

CF=0 és ZF=0

érték1>érték2. Az értékeket a rendszer aláíratlan egész számként kezeli.

B NAE

CF=1

value1<value2. Az értékeket a rendszer aláíratlan egész számként kezeli.

A feltételeket általában a cmp vagy teszt utasítások eredményének feldolgozására használják. Például

cmp eax, 5
jz equal

összehasonlítja a eax regisztert az 5-ös számmal a kifejezés (eax - 5) számításával, és az eredménynek megfelelően jelölőket állít be. Ha a kivonás eredménye nulla, akkor a zr zászló lesz beállítva, és a jz feltétel igaz lesz, ekkor az ugrás megtörténik.

Adattípusok

  • bájt: 8 bit

  • szó: 16 bit

  • dword: 32 bit

  • qword: 64 bit (beleértve a lebegőpontos dupla adattípust)

  • tword: 80 bit (beleértve a lebegőpontos kiterjesztett dupla)

  • oword: 128 bit

Jelölés

Az alábbi táblázat a szerelvény nyelvi utasításainak leírására használt jelölést jelzi.

Jelölés Jelentés

r, r1, r2...

Regiszterek

m

Memóriacím (további információért tekintse meg a következő Címzési módok szakaszt.)

#n

Azonnali állandó

r/m

Regiszter vagy memória

r/#n

Regiszter vagy közvetlen konstans

r/m/#n

Regiszter, memória vagy azonnali konstans

cc

Az előző Feltételek szakaszban felsorolt feltételkód.

T

"B", "W" vagy "D" (bájt, szó vagy duplaszó)

accT

Méret T akkumulátor: al ha T = "B", tengely, ha T = "W", vagy eax ha T = "D"

Címzési módok

Számos különböző címzési mód létezik, de mindegyik a T ptr [expr]formájában jelenik meg, ahol T valamilyen adattípus (lásd az előző Adattípusok szakaszt), expr pedig egy állandókat és regisztrátorokat tartalmazó kifejezés.

A legtöbb mód jelölése nagy nehézség nélkül levezethető. Például BYTE PTR [esi+edx*8+3] azt jelenti, hogy "használja az esi regiszter értékét, adja hozzá a edx regiszter értékének nyolcszorosát, adjon hozzá háromat, majd férjen hozzá a bájthoz az eredményül kapott címen."

Pipeline

A Pentium kettős kiadású, ami azt jelenti, hogy egy órajel alatt legfeljebb két műveletet hajthat végre. Azonban a szabályok arra vonatkozóan, hogy mikor képes egyszerre két műveletet végrehajtani (más néven párosítás), nagyon bonyolult.

Mivel az x86 egy CISC-processzor, nem kell aggódnia az ugrási késleltetési pontok miatt.

Szinkronizált memóriahozzáférés

A betöltési, módosítási és tárolási utasítások zárolási előtagot kaphatnak, amely az alábbi módon módosítja az utasítást:

  1. Az utasítás kiadása előtt a PROCESSZOR kiüríti az összes függőben lévő memóriaműveletet, hogy biztosítsa a megfelelőséget. Minden adat-előolvasás megszakítva.

  2. Az utasítás kiadása során a PROCESSZOR kizárólagos hozzáféréssel rendelkezik a buszhoz. Ez biztosítja a terhelési/módosítási/tárolási művelet atomiságát.

Az xchg utasítás automatikusan betartja az előző szabályokat, amikor értéket cserél a memóriával.

Az összes többi utasítás alapértelmezés szerint nem zárolásra van kapcsolva.

Ugrás előrejelzése

Feltétel nélküli ugrások várhatók.

A feltételes ugrásokat a program előrejelzi, attól függően, hogy azokat a legutóbbi végrehajtásukkor hajtották-e végre. A ugróelőzmények rögzítésére szolgáló gyorsítótár mérete korlátozott.

Ha a CPU-nak nincs feljegyzése arról, hogy a feltételes ugrást végrehajtották-e az utolsó végrehajtáskor, akkor a visszafelé irányuló feltételes ugrásokat végrehajtottként, míg az előre irányuló feltételes ugrásokat nem végrehajtottként jósolja meg.

Igazítás

Az x86 processzor automatikusan kijavítja a nem igazított memóriahozzáférést a teljesítmény csökkenése árán. Nincs kivétel.

A memóriahozzáférés akkor tekinthető igazítottnak, ha a cím az objektumméret egész számának többszöröse. Például az összes BYTE-hozzáférés igazodik (minden az 1 egész szám többszöröse), a WORD páros címekhez való hozzáférése igazított, a DWORD-címeknek pedig a 4 többszörösének kell lenniük az igazításhoz.

A zárolási előtagot nem szabad használni nem igazított memóriahozzáférésekhez.

Lásd még:

x64-architektúra

X86-64 Wikipedia