6. fejezet: A modern számítógép-architektúra alapjai az Assembly Language segítségével

6 Fejezet A Modern Szamitogep Architektura Alapjai Az Assembly Language Segitsegevel



6.1 Bevezetés

A modern általános célú számítógépeknek két típusa van: CISC és RISC. A CISC a Complex Instruction Set Computer rövidítése. A RISK a csökkentett utasításkészletű számítógép rövidítése. A 6502-es vagy 6510-es mikroprocesszorok, ahogyan a Commodore-64 számítógépre vonatkozik, jobban hasonlítanak a RISC architektúrára, mint a CISC architektúrára.

A RISC számítógépek általában rövidebb assembly nyelvű utasításokkal rendelkeznek (byte-ok száma szerint), mint a CISC számítógépek.







jegyzet : Akár CISC-ről, RISC-ről vagy régi számítógépről van szó, a periféria egy belső porttól indul, és a számítógép rendszeregységének (alapegységének) függőleges felületén lévő külső porton keresztül kifelé halad a külső eszközig.



A CISC számítógépek tipikus utasítását úgy tekinthetjük, mint amikor több rövid assembly nyelvi utasítást egy hosszabb assembly nyelvi utasításba egyesítünk, ami bonyolulttá teszi a kapott utasítást. Konkrétan egy CISC számítógép betölti az operandusokat a memóriából a mikroprocesszor-regiszterekbe, végrehajt egy műveletet, majd az eredményt visszatárolja a memóriába, mindezt egyetlen utasítással. Másrészt ez legalább három utasítás (rövid) a RISC számítógéphez.



A CISC számítógépek két népszerű sorozata létezik: az Intel mikroprocesszoros számítógépek és az AMD mikroprocesszoros számítógépek. Az AMD az Advanced Micro Devices rövidítése; ez egy félvezető gyártó cég. Az Intel mikroprocesszor-sorozat a fejlesztési sorrendben: 8086, 8088, 80186, 80286, 80386, 80486, Pentium, Core, i Series, Celeron és Xeon. A korai Intel mikroprocesszorokhoz, például a 8086-hoz és a 8088-hoz tartozó assembly nyelvi utasítások nem túl bonyolultak. Ezek azonban bonyolultak az új mikroprocesszorok számára. A CISC sorozat legújabb AMD mikroprocesszorai a Ryzen, az Opteron, az Athlon, a Turion, a Phenom és a Sempron. Az Intel és az AMD mikroprocesszorok x86 mikroprocesszorok néven ismertek.





Az ARM az Advanced RISC Machine rövidítése. Az ARM architektúrák a RISC processzorok családját határozzák meg, amelyek számos alkalmazásban használhatók. Míg sok Intel és AMD mikroprocesszort használnak az asztali személyi számítógépekben, sok ARM processzor beágyazott processzorként szolgál a biztonság szempontjából kritikus rendszerekben, például az autók blokkolásgátló fékeiben, valamint általános célú processzorként okosórákban, hordozható telefonokban, táblagépekben és laptopokban. . Bár mindkét típusú mikroprocesszor megtalálható kis és nagy eszközökben, a RISC mikroprocesszorok inkább a kis eszközökben találhatók meg, mint a nagy eszközökben.

Számítógépes Word
Ha egy számítógépet 32 ​​bites szószámítógépnek mondunk, az azt jelenti, hogy az információt az alaplap belső részén belül harminckét bites bináris kódok formájában tárolják, továbbítják és manipulálják. Ez azt is jelenti, hogy a számítógép mikroprocesszorában található általános célú regiszterek 32 bitesek. A 6502-es mikroprocesszor A, X és Y regiszterei általános célú regiszterek. Nyolc bit szélesek, így a Commodore-64 számítógép nyolc bites szószámítógép.



Némi szókincs
X86 számítógépek

A byte, word, doubleword, quadword és double-quadword jelentése a következő x86-os számítógépeken:

  • Byte : 8 bit
  • Szó : 16 bit
  • Duplaszó : 32 bit
  • Quadword : 64 bit
  • Dupla négyszó : 128 bit

ARM számítógépek
A byte, halfword, word és doubleword jelentése a következő az ARM számítógépeknél:

  • Byte : 8 bit
  • Legyen fél : 16 bit
  • Szó : 32 bit
  • Duplaszó : 64 bit

Figyelembe kell venni az x86 és az ARM nevek (és értékek) különbségeit és hasonlóságait.

jegyzet : Az előjelű egész számok mindkét számítógéptípusban kettős komplementerek.

Memória helye
A Commodore-64 számítógépen a memóriahely jellemzően egy bájt, de esetenként két egymást követő bájt is lehet, ha figyelembe vesszük a mutatókat (közvetett címzés). Egy modern x86-os számítógépben a memóriahely 16 egymást követő bájt, ha 16 bájtos (128 bites) kettős négyszóval foglalkozik, 8 egymást követő bájt 8 bájtos (64 bites) négyszóval, 4 egymást követő bájt kettős szóval. 4 bájt (32 bit), 2 egymást követő bájt 2 bájtos szó (16 bit) és 1 bájt bájt (8 bit) kezelése esetén. Egy modern ARM számítógépben a memóriahely 8 egymást követő bájt, ha 8 bájtos (64 bites) duplaszóval, 4 egymást követő bájt 4 bájtos (32 bites) szóval, 2 egymást követő bájt félszóval. 2 bájt (16 bit), és 1 bájt, ha egy bájttal (8 bit) foglalkozik.

Ez a fejezet elmagyarázza, mi a közös a CISC és RISC architektúrákban, és mi a különbség köztük. Ez a 6502 µP-vel és a commodore-64 számítógéppel összehasonlítva történik, ahol alkalmazható.

6.2 A modern számítógép alaplapi blokkdiagramja

A PC a személyi számítógép rövidítése. Az alábbiakban egy általános alapblokkvázlat látható egy modern alaplaphoz, egyetlen mikroprocesszorral a személyi számítógéphez. CISC vagy RISC alaplapot képvisel.


6.21. ábra A modern számítógép alaplapi blokkdiagramja

Az ábrán három belső port látható, de a gyakorlatban több van. Minden portnak van egy regisztere, amely maga a port is tekinthető. Minden port áramkörnek van legalább egy másik regisztere, amelyet „állapotregiszternek” nevezhetünk. Az állapotregiszter jelzi a program portját, amely megszakítási jelet küld a mikroprocesszornak. Van egy megszakításvezérlő áramkör (nincs ábrázolva), amely különbséget tesz a különböző portokról érkező megszakítási vonalak között, és csak néhány sorral rendelkezik a µP-hez.

Az ábrán a HD.C a merevlemez-kártyát jelenti. A NIC a Network Interface Card rövidítése. A merevlemez-kártya (áramkör) ahhoz a merevlemezhez csatlakozik, amely a modern számítógép alapegységében (rendszeregységében) található. A hálózati interfész kártya (áramkör) külső kábelen keresztül csatlakozik egy másik számítógéphez. Az ábrán egy port és egy DMA található (lásd a következő ábrát), amelyek a merevlemez-kártyához és/vagy a hálózati interfészkártyához csatlakoznak. A DMA a közvetlen memóriaelérés rövidítése.

Emlékezzen a Commodore-64 számítógép fejezetből, hogy ahhoz, hogy a bájtokat a memóriából a lemezmeghajtóra vagy egy másik számítógépre küldjük, minden bájtot a mikroprocesszorban lévő regiszterbe kell másolni, mielőtt a megfelelő belső portra másolnák, majd automatikusan a készülékhez. Ahhoz, hogy a bájtokat a lemezmeghajtóról vagy egy másik számítógépről a memóriába fogadhassuk, minden bájtot át kell másolni a megfelelő belső portregiszterből egy mikroprocesszor-regiszterbe, mielőtt a memóriába másolnák. Ez általában sokáig tart, ha az adatfolyamban nagy a bájtok száma. A gyors átvitel megoldása a közvetlen memóriahozzáférés (áramkör) használata a mikroprocesszoron való áthaladás nélkül.

A DMA áramkör a port és a HD között van. C vagy NIC. A DMA áramkör közvetlen memória-hozzáférésével a nagy bájtfolyamok átvitele közvetlenül történik a DMA áramkör és a memória (RAM) között, a mikroprocesszor folyamatos részvétele nélkül. A DMA a címbuszt és az adatbuszt használja a µP helyett. Az átvitel teljes időtartama rövidebb, mintha µP keményet használnánk. Mind a HD C., mind a NIC használja a DMA-t, ha nagy adatfolyammal (bájttal) rendelkeznek a RAM-mal (memóriával) való átvitelhez.

A GPU a Graphics Processing Unit rövidítése. Az alaplapon ez a blokk felelős a szöveg és a mozgó vagy állóképek képernyőre küldéséért.

A modern számítógépeknél (PC-knél) nincs csak olvasható memória (ROM). Létezik azonban a BIOS vagy az UEFI, amely egyfajta nem felejtő RAM. A BIOS-ban lévő információkat valójában egy akkumulátor tartja fenn. Az akkumulátor az, ami tulajdonképpen az óraidőzítőt is karbantartja, a számítógépnek megfelelő időpontban és dátumban. Az UEFI-t a BIOS után találták fel, és felváltotta a BIOS-t, bár a BIOS még mindig meglehetősen releváns a modern számítógépekben. Ezekről később bővebben fogunk beszélni!

A modern PC-kben a µP és a belső port áramkörök (és a memória) közötti cím- és adatbuszok nem párhuzamos buszok. Ezek soros buszok, amelyeknek két vezetőre van szükségük az egyik irányú átvitelhez, és egy másik két vezetőre az ellenkező irányú átvitelhez. Ez például azt jelenti, hogy 32 bitet lehet sorosan küldeni (egyik bitet a másik után) bármelyik irányba.

Ha a soros átvitel csak egy irányban történik két vezetővel (két vonallal), akkor azt félduplexnek mondjuk. Ha a soros átvitel mindkét irányban négy vezetővel történik, egy pár mindkét irányban, ez full-duplexnek mondható.

A modern számítógép teljes memóriája még mindig bájthelyek sorozatából áll: nyolc bit bájtonként. Egy modern számítógép memóriája legalább 4 giga bájt = 4 x 210 x 2 10 x 2 10 = 4 x 1 073 741 824 10 bájt = 4 x 1024 10/al> x 1024 10 x 1024 10 = 4 x 1 073 741 824 10 .

jegyzet : Bár az előző alaplapon nincs időzítő áramkör, minden modern alaplap rendelkezik időzítő áramkörrel.

6.3 Az x64 számítógép-architektúra alapjai

6.31 Az x64 regiszterkészlet
Az x86 sorozatú mikroprocesszorok 64 bites mikroprocesszora egy 64 bites mikroprocesszor. Meglehetősen modern az azonos sorozatú 32 bites processzor cseréje. A 64 bites mikroprocesszor általános célú regiszterei és neveik a következők:


6.31. ábra Általános célú regiszterek x64-hez

Az ábrán tizenhat (16) általános célú regiszter látható. Ezen regiszterek mindegyike 64 bites széles. A bal felső sarokban lévő regiszterre nézve a 64 bitet RAX-ként azonosítjuk. Ugyanennek a regiszternek az első 32 bitje (jobbról) EAX-ként van azonosítva. Ugyanennek a regiszternek az első 16 bitje (jobbról) AX-ként van azonosítva. Ugyanennek a regiszternek a második bájtja (jobbról) AH-ként van azonosítva (H itt magas értéket jelent). És az első bájt (ennek a regiszternek) AL-ként van azonosítva (L itt alacsony értéket jelent). A jobb alsó sarokban lévő regiszterre nézve a 64 bitet R15-ként azonosítjuk. Ugyanennek a regiszternek az első 32 bitje R15D. Ugyanennek a regiszternek az első 16 bitje R15W. És az első bájt R15B-ként van azonosítva. A többi regiszter (és az alregiszterek) neve is hasonlóan magyarázható.

Van némi különbség az Intel és az AMD µP között. Az ebben a részben található információk az Intelre vonatkoznak.

A 6502 µP esetében a programszámláló regiszter (közvetlenül nem elérhető), amely a következő végrehajtandó utasítást tartalmazza, 16 bit széles. Itt (x64) a programszámlálót utasításmutatónak hívják, és 64 bit széles. RIP címkével van ellátva. Ez azt jelenti, hogy az x64 µP legfeljebb 264 = 1,844674407 x 1019 (valójában 18 446 744 073 709 551 616) memóriabájt helyet tud megcímezni. A RIP nem általános célú nyilvántartás.

A Stack Pointer Register vagy RSP a 16 általános célú regiszter közé tartozik. A memória utolsó verembejegyzésére mutat. A 6502 µP-hez hasonlóan az x64 stackje lefelé növekszik. Az x64 esetében a RAM-ban lévő verem az alprogramok visszatérési címeinek tárolására szolgál. Az „árnyéktér” tárolására is szolgál (lásd a következő tárgyalást).

A 6502 µP 8 bites processzorállapot-regiszterrel rendelkezik. Az x64 megfelelőjét RFLAGS regiszternek nevezik. Ez a regiszter tárolja azokat a jelzőket, amelyeket a műveletek eredményéhez és a processzor vezérléséhez használunk (µP). 64 bit széles. A magasabb 32 bit le van foglalva, és jelenleg nem használatos. Az alábbi táblázat az RFLAGS regiszterben gyakran használt bitek nevét, indexét és jelentését tartalmazza:

6.31.1. táblázat
Leggyakrabban használt RFLAGS zászlók (bitek)
Szimbólum Bit Név Célja
CF 0 Visz Akkor van beállítva, ha egy aritmetikai művelet átvitelt vagy kölcsönzést generál az eredmény legjelentősebb bitjéből; különben törölve. Ez a jelző túlcsordulási feltételt jelez az előjel nélküli egész számok aritmetikához. A többszörös pontosságú aritmetikában is használják.
PF 2 Paritás Akkor van beállítva, ha az eredmény legkisebb jelentőségű bájtja páros számú 1 bitet tartalmaz; különben törölve.
NAK,-NEK 4 Beállítani Akkor van beállítva, ha egy aritmetikai művelet átvitelt vagy kölcsönzést generál az eredmény 3. bitjéből; különben törölve. Ez a jelző a bináris kódolású decimális (BCD) aritmetikában használatos.
ZF 6 Nulla Akkor van beállítva, ha az eredmény nulla; különben törölve.
SF 7 Jel Akkor van beállítva, ha egyenlő az eredmény legjelentősebb bitjével, amely egy előjeles egész szám előjelbitje (0 pozitív értéket, 1 negatív értéket jelöl).
NAK,-NEK tizenegy Túlcsordulás Akkor van beállítva, ha az egész eredmény túl nagy pozitív szám vagy túl kicsi negatív szám (az előjelbit nélkül) ahhoz, hogy beleférjen a cél operandusba; különben törölve. Ez a jelző egy túlcsordulási feltételt jelez az előjeles egész (kettős komplementer) aritmetika számára.
DF 10 Irány Akkor van beállítva, ha az iránykarakterlánc utasítások működnek (növekedés vagy csökkentés).
ID huszonegy Azonosítás Akkor van beállítva, ha a változtathatóság a CPUID utasítás jelenlétét jelzi.

A korábban jelzett tizennyolc 64 bites regiszteren kívül az x64 architektúra µP nyolc 80 bites szélességű regiszterrel rendelkezik a lebegőpontos aritmetika számára. Ez a nyolc regiszter MMX regiszterként is használható (lásd a következő tárgyalást). Az XMM számára tizenhat 128 bites regiszter is létezik (lásd a következő tárgyalást).

Ez nem minden a nyilvántartásokról szól. Több x64-regiszter létezik, amelyek szegmensregiszterek (az x64-ben többnyire nem használtak), vezérlőregiszterek, memóriakezelő regiszterek, hibakereső regiszterek, virtualizációs regiszterek, teljesítményregiszterek, amelyek mindenféle belső paramétert követnek (gyorsítótár találatai/kihagyások, végrehajtott mikroműveletek, időzítés). , és még sok más).

SIMD

A SIMD a Single Instruction Multiple Data rövidítése. Ez azt jelenti, hogy egy assembly nyelvű utasítás több adatra is hathat egyidejűleg egy mikroprocesszorban. Vegye figyelembe a következő táblázatot:

1 2 3 4 5 6 7 8
+ 9 10 tizenegy 12 13 14 tizenöt 16
= 10 12 14 16 18 húsz 22 24

Ebben a táblázatban nyolc számpárt adunk párhuzamosan (ugyanabban az időtartamban), hogy nyolc választ kapjunk. Egy assembly nyelvi utasítás képes elvégezni a nyolc párhuzamos egész összeadást az MMX regiszterekben. Hasonló dolgot lehet tenni az XMM regiszterekkel is. Tehát vannak MMX utasítások az egész számokhoz és XMM utasítások a floatokhoz.

6.32 Memóriatérkép és az x64

Ha az utasításmutató (programszámláló) 64 bites, ez azt jelenti, hogy 264 = 1,844674407 x 1019 memóriabájt helyek címezhetők meg. Hexadecimálisban a legmagasabb bájt helye FFFF,FFFF,FFFF,FFFF16. Ma egyetlen közönséges számítógép sem tud ekkora (teljes) memóriaterületet biztosítani. Tehát egy megfelelő memóriatérkép az x64 számítógéphez a következő:

Figyelje meg, hogy a 0000,8000,0000,000016 és FFFF,7FFF,FFFF,FFFF16 közötti résnek nincs memóriahelye (nincs memória RAM-bank). Ez a különbség FFFF,0000,0000,000116, ami elég nagy. A kanonikus felső felén az operációs rendszer, míg a kanonikus alsó felén a felhasználói programok (alkalmazások) és adatok találhatók. Az operációs rendszer két részből áll: egy kis UEFI (BIOS) és egy nagy részből, amelyek a merevlemezről töltődnek be. A következő fejezet bővebben szól a modern operációs rendszerekről. Vegye figyelembe a hasonlóságot ezzel a memóriatérképpel és a Commodore-64-gyel, amikor a 64 KB sok memóriának tűnhetett.

Ebben az összefüggésben az operációs rendszert nagyjából „kernelnek” nevezik. A kernel hasonló a Commodore-64 számítógép Kernaljához, de sokkal több szubrutinja van.

Az x64 endianness kicsi, ami azt jelenti, hogy egy hely esetében az alacsonyabb cím a memória alacsonyabb tartalmi bájtjára mutat.

6.33 Összeállítási nyelvi címzési módok x64-hez

A címzési módok azok a módok, amelyek segítségével egy utasítás hozzáférhet az µP regiszterekhez és a memóriához (beleértve a belső portregisztereket is). Az x64 számos címzési móddal rendelkezik, de itt csak az általánosan használt címzési módok vannak megcímezve. Az alábbi utasítások általános szintaxisa:

opcode rendeltetési hely, forrás

A decimális számokat előtag vagy utótag nélkül írjuk. A 6502-nél a forrás implicit. Az x64-nek több műveleti kódja van, mint a 6502-nek, de némelyik műveleti kódnak ugyanaz a megjegyzés. Az egyes x64 utasítások változó hosszúságúak, és 1 és 15 bájt közöttiek lehetnek. Az általánosan használt címzési módok a következők:

Azonnali címzési mód
Itt a forrás operandus egy tényleges érték, és nem egy cím vagy címke. Példa (olvasd el a megjegyzést):

ADD EAX, 14 ; add hozzá a 64 bites RAX 14 és 32 bites EAX decimális értékét, a válasz az EAX-ben marad (célállomás)

Regisztráljon a Címzési mód regisztrációjához
Példa:

ADD R8B, AL ; adjunk hozzá 8 bites RAX AL-t a 64 bites R8 R8B-hez – a válaszok az R8B-ben maradnak (célállomás)

Közvetett és indexelt címzési mód
Az indirekt címzés a 6502 µP-vel azt jelenti, hogy az utasításban az adott cím helye rendelkezik a végső hely tényleges címével (mutatójával). Hasonló dolog történik az x64-el is. Az indexcímzés a 6502 µP-vel azt jelenti, hogy az utasításban egy µP regiszter tartalma hozzáadódik az adott címhez, hogy az érvényes cím legyen. Hasonló dolog történik az x64-el is. Ezenkívül az x64-gyel a regiszter tartalma 1-gyel vagy 2-vel, 4-gyel vagy 8-cal is megszorozható, mielőtt az adott címhez adná. Az x64 mov (másolás) utasítása kombinálhatja mind az indirekt, mind az indexelt címzést. Példa:

MOV R8W, 1234[8*RAX+RCX] ; szó mozgatása a címre (8 x RAX + RCX) + 1234

Itt az R8W rendelkezik az R8 első 16 bitjével. A megadott cím 1234. A RAX regiszter egy 64 bites számmal rendelkezik, amelyet meg kell szorozni 8-cal. Az eredményt hozzáadjuk a 64 bites RCX regiszter tartalmához. Ez a második eredmény hozzáadódik a megadott címhez, amely 1234, hogy megkapja a tényleges címet. Az érvényes cím helyén lévő szám az R8 regiszter első 16 bites helyére (R8W) kerül (másolódik), lecserélve az ott lévőt. Figyelje meg a szögletes zárójelek használatát. Ne feledje, hogy az x64-ben egy szó 16 bit széles.

RIP relatív címzés
A 6502 µP esetében a relatív címzést csak az elágazási utasításokkal használják. Ott a műveleti kód egyetlen operandusa egy eltolás, amelyet hozzáadunk vagy kivonunk a programszámláló tartalmából a tényleges utasításcímhez (nem adatcímhez). Hasonló dolog történik az x64-el, ahol a programszámlálót utasításmutatónak hívják. Az x64-es utasításnak nem kell csak elágazó utasításnak lennie. Példa a RIP-relatív címzésre:

MOV AL, [RIP]

A RAX AL egy 8 bites előjeles számmal rendelkezik, amelyet hozzáadnak vagy kivonnak a RIP (64 bites utasításmutató) tartalmából, hogy a következő utasításra mutassanak. Vegye figyelembe, hogy a forrás és a cél kivételesen felcserélődik ebben az utasításban. Vegye figyelembe a szögletes zárójelek használatát is, amelyek a RIP tartalmára utalnak.

6.34 Az x64 általánosan használt utasításai

A következő táblázatban a * a műveleti kódok egy részhalmazának különböző lehetséges utótagjait jelenti:

6.34.1. táblázat
Gyakran használt utasítások x64-ben
Opcode Jelentése
MOV Áthelyezés (másolás) a memóriába/regiszterek közé/között
CMOV* Különféle feltételes mozdulatok
XCHG Csere
BSWAP Bájtcsere
PUSH/POP Veremhasználat
ADD/ADC Hozzáadás/hordással
SUB/SBC Kivonás/hordással
MUL/IMUL Szorzás/előjel nélküli
DIV/IDIV Felosztás/jel nélküli
INC/DEC Növekedés/csökkentés
NEG Negatív
CMP Hasonlítsa össze
ÉS/VAGY/XOR/NEM Bitenkénti műveletek
SHR/SAR Shift jobbra logikai/aritmetikai
SHL/SAL Eltolás balra logikai/aritmetikai
ROR/ROLE Forgatás jobbra/balra
RCR/RCL Forgassa jobbra/balra a hordfejen keresztül
BT/BTS/BTR Bitteszt/és beállítás/és visszaállítás
JMP Feltétel nélküli ugrás
JE/JNE/JC/JNC/J* Ugrás, ha egyenlő/nem egyenlő/visz/nem cipel/sok más
SÉTA/SÉTA/SÉTA Hurok ECX-el
HÍVÁS/RET Alprogram hívása/return
NOP Nincs művelet
CPUID CPU információ

Az x64 rendelkezik szorzás és osztás utasításokkal. µP-ben szorzó és osztás hardver áramkörei vannak. A 6502 µP nem rendelkezik szorzó és osztás hardver áramkörrel. A szorzást és osztást gyorsabban végezzük el hardverrel, mint szoftverrel (beleértve a bitek eltolását is).

String Utasítások
Számos karakterlánc-utasítás létezik, de itt csak a MOVS (for move string) utasításról kell szót ejteni a C000 címen kezdődő karakterlánc másolására. H . Kezdje a C100 címen H , használja a következő utasítást:

MOVS [C100H], [C000H]

Jegyezze meg a H utótagot a hexadecimális értékhez.

6.35 Looping in x64

A 6502 µP elágazó utasításokkal rendelkezik a hurkoláshoz. Az elágazási utasítás egy olyan címre ugrik, amelyen az új utasítás található. A cím helyét „huroknak” nevezhetjük. Az x64 LOOP/LOOPE/LOOPNE utasításokkal rendelkezik a hurkoláshoz. Ezeket a fenntartott assembly nyelvű szavakat nem szabad összetéveszteni a „hurok” címkével (idézőjelek nélkül). A viselkedés a következő:

A LOOP csökkenti az ECX-et, és ellenőrzi, hogy az ECX nem nulla-e. Ha ez a feltétel (nulla) teljesül, akkor a megadott címkére ugrik. Ellenkező esetben meghiúsul (folytassa a többi utasítást a következő beszélgetésben).

A LOOPE csökkenti az ECX-et, és ellenőrzi, hogy az ECX nem nulla (lehet például 1), és a ZF értéke 1-re van állítva. Ha ezek a feltételek teljesülnek, a címkére ugrik. Ellenkező esetben átesik.

A LOOPNE csökkenti az ECX-et, és ellenőrzi, hogy az ECX nem nulla, és a ZF NINCS beállítva (azaz nulla legyen). Ha ezek a feltételek teljesülnek, a címkére ugrik. Ellenkező esetben átesik.

Az x64 esetén az RCX regiszter vagy annak alrészei, mint az ECX vagy CX, a számláló egész számot tartalmazza. A LOOP utasításokkal a számláló általában lefelé számol, minden ugrás (hurok) esetén 1-gyel csökken. A következő hurkolt kódszegmensben az EAX regiszter száma 0-ról 10-re növekszik tíz iteráció alatt, míg az ECX-ben lévő szám 10-szer csökken (olvassa el a megjegyzéseket):

MOV EAX, 0 ;
MOV ECX, 10 ; alapértelmezés szerint 10-szer számol vissza, minden iterációhoz egyszer
címke:
INC EAX ; növelje az EAX-et huroktestként
LOOP címke ; csökkentse az EAX-et, és ha az EAX nem nulla, hajtsa végre újra a ciklus törzsét a „label:”-ből.

A hurokkódolás a „label:”-vel kezdődik. Vegye figyelembe a kettőspont használatát. A hurokkódolás a „LOOP címkével” végződik, amely az EAX csökkentését írja ki. Ha a tartalma nem nulla, térjen vissza a „label:” utáni utasításhoz, és hajtsa végre újra a lefelé érkező utasításokat (az összes törzsutasítást) a „LOOP label”ig. Vegye figyelembe, hogy a „címkének” továbbra is lehet másik neve.

6.36 x64 bemenet/kimenet

A fejezet ezen része az adatok kimeneti (belső) portra történő elküldésével vagy az adatok bemeneti (belső) portról történő fogadásával foglalkozik. A lapkakészlet nyolc bites portokkal rendelkezik. Bármely két egymást követő 8 bites port 16 bites portként kezelhető, és bármely négy egymást követő port lehet 32 ​​bites port. Ily módon a processzor 8, 16 vagy 32 bitet tud átvinni egy külső eszközre vagy onnan.

Az információ a processzor és a belső port között kétféleképpen továbbítható: az úgynevezett memória-leképezett bemenet/kimenet vagy külön bemeneti/kimeneti címtér használatával. A memória-leképezett I/O olyan, mint ami a 6502-es processzorral történik, ahol a portcímek valójában a teljes memóriaterület részét képezik. Ebben az esetben, amikor az adatokat egy adott címre küldjük, az egy portra kerül, és nem egy memóriabankba. A portoknak külön I/O címterük lehet. Ez utóbbi esetben az összes memóriabank címe nullától kezdődik. Külön címtartomány van 0000H és FFFF16 között. Ezeket a lapkakészlet portjai használják. Az alaplap úgy van programozva, hogy ne tévessze össze a memórialeképezett I/O és a külön I/O címteret.

Memória-leképezett I/O
Ezzel a portok memóriahelynek számítanak, és a memória és a µP közötti normál műveleti kódokat használják a µP és a portok közötti adatátvitelre. Tehát egy bájt áthelyezéséhez az F000H címen lévő portról a RAX:EAX:AX:AL µP regiszterbe, tegye a következőket:

MOV AL, [F000H]

Egy karakterlánc áthelyezhető a memóriából egy portra és fordítva. Példa:

MOVS [F000H], [C000H] ; a forrás C000H, a cél pedig az F000H port.

Külön I/O címtér

Ehhez a bemenetre és a kimenetre vonatkozó speciális utasításokat kell használni.

Egyedi tételek átvitele
Az átvitel processzorregisztere a RAX. Valójában ez a RAX:EAX a duplaszó, a RAX:EAX:AX ​​a szó és a RAX:EAX:AX:AL a bájt. Tehát egy bájt átviteléhez az FFF0h portról a RAX:EAX:AX:AL fájlba írja be a következőt:

IN AL, [FFF0H]

A fordított átvitelhez írja be a következőket:

OUT [FFF0H], AL

Tehát az egyes tételeknél az utasítások BE és KI. A port címe az RDX:EDX:DX regiszterben is megadható.

Karakterláncok átvitele
Egy karakterlánc átvihető a memóriából egy chipset portra és fordítva. Egy karakterlánc átviteléhez az FFF0H című portról a memóriába, kezdje a C100H-val, és írja be:

INS [ESI], [DX]

amelynek ugyanaz a hatása, mint:

INS [EDI], [DX]

A programozónak az FFF0H kétbájtos portcímét kell beírnia az RDX:EDX:Dx regiszterbe, a C100H kétbájtos címét pedig az RSI:ESI vagy RDI:EDI regiszterbe. A fordított átvitelhez tegye a következőket:

INS [DX], [ESI]

amelynek ugyanaz a hatása, mint:

INS [DX], [EDI]

6.37 A verem x64-ben

A 6502-es processzorhoz hasonlóan az x64-es processzornak is van egy halom RAM-ja. Az x64 stackje 2 lehet 16 = 65 536 bájt hosszú, vagy lehet 2 is 32 = 4 294 967 296 bájt hosszú. Lefelé is nő. Amikor egy regiszter tartalma a verembe kerül, az RSP veremmutató száma 8-cal csökken. Ne feledje, hogy az x64 memóriacíme 64 bit széles. A veremmutatóban az µP-ben lévő érték a verem következő helyére mutat a RAM-ban. Amikor egy regiszter tartalmát (vagy az egyik operandus értékét) a veremből egy regiszterbe ugrik, az RSP veremmutatóban lévő szám 8-cal nő. Az operációs rendszer határozza meg a verem méretét és a RAM-ban, hogy hol kezdődik. és lefelé nő. Ne feledje, hogy a verem egy utolsó-be-első-ki (LIFO) struktúra, amely ebben az esetben lefelé növekszik és felfelé zsugorodik.

Az µP RBX regiszter tartalmának verembe helyezéséhez tegye a következőket:

PUSH RBX

Ha a verem utolsó bejegyzését vissza szeretné helyezni az RBX-be, tegye a következőket:

POP RBX

6.38 Eljárás x64-ben

Az x64 szubrutinját „eljárásnak” nevezik. A verem itt többet használ, mint a 6502 µP esetében. Az x64 eljárás szintaxisa a következő:

proc_name:
eljárási szerv

jobb

Mielőtt folytatná, vegye figyelembe, hogy az x64 szubrutin műveleti kódjai és címkéi (általában az összeállítási nyelvi utasítások) nem tesznek különbséget a kis- és nagybetűk között. Ez a proc_name ugyanaz, mint a PROC_NAME. A 6502-höz hasonlóan az eljárásnév (címke) neve az assembly nyelv szövegszerkesztőjében egy új sor elején kezdődik. Ezt kettőspont követi, és nem szóköz és műveleti kód, mint a 6502-nél. A szubrutin törzse következik, amely RET-re végződik, nem pedig RTS-re, mint a 6502 µP esetében. A 6502-höz hasonlóan a törzsben minden utasítás, beleértve a RET-et is, nem a sor elején kezdődik. Vegye figyelembe, hogy itt egy címke 8 karakternél hosszabb lehet. Ennek az eljárásnak a gépelt eljárás felülről vagy alul történő meghívásához tegye a következőket:

CALL proc_name

A 6502-nél a címke neve csak a híváshoz szükséges típus. Itt azonban a fenntartott „CALL” vagy „call” szó kerül begépelésre, majd szóköz után az eljárás (szubrutin) neve.

Az eljárások kezelésekor általában két eljárás létezik. Az egyik eljárás hívja a másikat. A hívó eljárást (amelynek hívási utasítása van) hívónak, a meghívott eljárást hívónak nevezzük. Van egy egyezmény (szabályok), amit be kell tartani.

A hívó szabályai

A hívónak be kell tartania a következő szabályokat egy szubrutin meghívásakor:

1. Egy szubrutin hívása előtt a hívónak el kell mentenie bizonyos, hívó által mentett regiszterek tartalmát verembe. A hívó fél által mentett regiszterek az R10, R11, és minden olyan regiszter, amelybe a paraméterek bekerülnek (RDI, RSI, RDX, RCX, R8, R9). Ha ezeknek a regisztereknek a tartalmát meg kell őrizni a szubrutinhívás során, a RAM-ba való mentés helyett tolja őket a verembe. Ezeket azért kell megtenni, mert a regisztereket a hívott félnek kell használnia a korábbi tartalom törléséhez.

2. Ha például két számot kell hozzáadni, akkor a két szám a veremnek átadandó paraméter. A paraméterek szubrutinnak való átadásához tegyen belőlük hatot sorrendben a következő regiszterekbe: RDI, RSI, RDX, RCX, R8, R9. Ha hatnál több paramétere van az alprogramnak, a többit fordított sorrendben tolja a verembe (azaz az utolsó paramétert először). Mivel a verem növekszik, az extra paraméterek közül az első (valójában a hetedik paraméter) a legalacsonyabb címen kerül tárolásra (ezt a paraméter-inverziót a történelem során arra használták, hogy a függvényeket (szubrutinokat) változó számú paraméterrel adják át).

3. A szubrutin (eljárás) hívásához használja a hívási utasítást. Ez az utasítás a visszatérési címet a veremben lévő paraméterek (legalacsonyabb pozíció) és a szubrutinkód elágazásai tetejére helyezi.

4. A szubrutin visszatérése után (azaz közvetlenül a hívási utasítást követően) a hívónak el kell távolítania minden további paramétert (a regiszterekben tárolt haton kívül) a veremből. Ez visszaállítja a verem a hívás előtti állapotát.

5. A hívó számíthat arra, hogy megtalálja az alprogram visszatérési értékét (címét) a RAX regiszterben.

6. A hívó visszaállítja a hívó által elmentett regiszterek tartalmát (R10, R11 és a paraméterátadási regiszterek bármelyike) úgy, hogy kiveszi őket a veremből. A hívó feltételezheti, hogy az alprogram nem módosított más regisztereket.

A hívási konvenció felépítéséből adódóan jellemzően előfordul, hogy ezen lépések némelyike ​​(vagy a legtöbb) nem módosít a veremben. Ha például hat vagy kevesebb paraméter van, akkor ebben a lépésben semmi sem kerül a verembe. Hasonlóképpen, a programozók (és fordítók) általában az 1. és 6. lépésben nem tartják be a hívó fél által mentett regiszterekből azokat az eredményeket, amelyekre számítanak, hogy megakadályozzák a túlzott lökéseket és durranásokat.

Két másik módja is van a paraméterek szubrutinnak való átadásának, de ezekkel az online karrierkurzus nem foglalkozik. Egyikük magát a veremet használja az általános célú regiszterek helyett.

A Callee szabályai

A hívott szubrutin definíciójának be kell tartania a következő szabályokat:

1. Rendelje ki a lokális változókat (az eljárás során kifejlesztett változókat) a regiszterek segítségével vagy helyet hagyva a veremben. Emlékezzünk vissza, a verem lefelé növekszik. Tehát, hogy helyet hagyjunk a verem tetején, a veremmutatót csökkenteni kell. Az összeg, amellyel a veremmutató csökken, a helyi változók szükséges számától függ. Például, ha szükség van egy helyi lebegőpontra és egy helyi hosszúra (összesen 12 bájt), akkor a veremmutatót 12-vel kell csökkenteni, hogy helyet biztosítson ezeknek a helyi változóknak. Egy magas szintű nyelvben, mint például a C, ez a változók deklarálását jelenti az értékek hozzárendelése (inicializálása) nélkül.

2. Ezután el kell menteni minden olyan regiszter értékét, amely a kijelölt hívott által mentett (a hívó által nem mentett általános célú regiszterek), amelyeket a funkció használ. A regiszterek mentéséhez tolja őket a verembe. A hívott fél által mentett regiszterek az RBX, RBP és az R12-R15 (az RSP-t a hívási megállapodás is megőrzi, de ebben a lépésben nem kell a verembe nyomni).

E három művelet végrehajtása után folytatódhat az alprogram tényleges működése. Amikor az alprogram készen áll a visszatérésre, a híváskonvenció szabályai folytatódnak.

3. Amikor az alprogram elkészült, az alprogram visszatérési értékét el kell helyezni a RAX-ba, ha még nincs ott.

4. Az alprogramnak vissza kell állítania a módosított hívott által elmentett regiszterek (RBX, RBP és R12-R15) régi értékeit. A regiszter tartalma a veremből való kiemeléssel áll vissza. Ne feledje, hogy a regisztereket a tolásuk fordított sorrendjében kell felugrani.

5. Ezután felszabadítjuk a helyi változókat. Ennek legegyszerűbb módja, ha hozzáadja az RSP-hez ugyanazt az összeget, amelyet az 1. lépésben levontak belőle.

6. Végül egy ret utasítás végrehajtásával visszatérünk a hívóhoz. Ez az utasítás megkeresi és eltávolítja a megfelelő visszaküldési címet a veremből.

Példa a hívó szubrutin törzsére egy másik „myFunc” szubrutin meghívásához (olvassa el a megjegyzéseket):

; Szeretnénk meghívni egy „myFunc” függvényt, amely hármat igényel
; integer paraméter. Az első paraméter a RAX-ban található.
; A második paraméter a 456 konstans. Harmadik
; paraméter a 'variabl' memóriahelyen van

push rdi ; Az rdi param lesz, ezért menteni kell
; long retVal = myFunc (x, 456, z);

mov rdi , rax ; tegye az első paramétert az RDI-be
mov rsi, 456 ; tegye a második paramétert az RSI-be
mov rdx , [variabl] ; helyezze be a harmadik paramétert az RDX-be

hívja a myFunc-ot; hívja meg a függvényt

pop rdi ; visszaállítja a mentett RDI értéket
; A myFunc visszatérési értéke már elérhető a RAX-ban

Példa a hívott függvényre (myFunc) (olvassa el a megjegyzéseket):

myFunc:
; ∗∗∗ Szabványos szubrutin prológus ∗∗∗
sub rsp, 8; hely egy 64 bites helyi változó (eredmény) számára az „al” műveleti kód használatával

push rbx ; hívott fél mentése-regiszterek mentése
push rbp ; mindkettőt a myFunc fogja használni

; ∗∗∗ Szubrutin Test ∗∗∗
mov rax , rdi ; 1. paramétert a RAX-hoz
mov rbp , rsi ; 2. paramétert az RBP-hez
mov rbx, rdx; 3. paraméter az rb x-hez
mov [rsp+16], rbx; helyezze be az rbx-et a helyi változóba
add [rsp + 1 6], rbp; add hozzá az rbp-t a helyi változóhoz
mov rax, [rsp +16]; A helyi változó mov tartalma a RAX-ba
; (visszatérési érték/végeredmény)

; ∗∗∗ Szabványos szubrutin epilógus ∗∗∗
pop rbp ; hívott fél mentési nyilvántartásainak helyreállítása
pop rbx ; fordítva, amikor megnyomják
adjunk hozzá rsp-t, 8 ; helyi változó(k) felszabadítása. A 8 8 bájtot jelent
ret ; pop top érték a veremből, ugorj oda

6.39 Megszakítások és kivételek x64 esetén

A processzor két mechanizmust biztosít a programvégrehajtás megszakítására, megszakításokra és kivételekre:

  • A megszakítás egy aszinkron (bármikor megtörténhet) esemény, amelyet általában egy I/O eszköz vált ki.
  • Kivétel egy szinkron esemény (amely a kód végrehajtása során történik, előre programozva, valamilyen esemény alapján), amely akkor jön létre, amikor a processzor egy vagy több előre meghatározott feltételt észlel egy utasítás végrehajtása közben. A kivételek három osztálya van megadva: hibák, csapdák és megszakítások.

A processzor a megszakításokra és a kivételekre lényegében azonos módon reagál. Ha megszakítást vagy kivételt jelez, a processzor leállítja az aktuális program vagy feladat végrehajtását, és átvált egy olyan kezelő eljárásra, amely kifejezetten a megszakítási vagy kivételi feltétel kezelésére van írva. A processzor az Interrupt Descriptor Table (IDT) bejegyzésén keresztül éri el a kezelő eljárást. Amikor a kezelő befejezte a megszakítás vagy kivétel kezelését, a programvezérlő visszakerül a megszakított programhoz vagy feladathoz.

Az operációs rendszer, a végrehajtó és/vagy eszköz-illesztőprogramok általában az alkalmazásprogramoktól vagy feladatoktól függetlenül kezelik a megszakításokat és kivételeket. Az alkalmazási programok azonban hozzáférhetnek az operációs rendszerbe beépített megszakítás- és kivételkezelőkhöz, vagy végrehajthatják azt az assembly nyelvű hívásokon keresztül.

Tizennyolc (18) előre meghatározott megszakítás és kivétel van meghatározva, amelyek az IDT bejegyzéseihez vannak társítva. Kétszázhuszonnégy (224) felhasználó által meghatározott megszakítás is létrehozható és társítható a táblához. Az IDT-ben minden megszakítást és kivételt egy szám azonosít, amelyet „vektornak” neveznek. A 6.39.1. táblázat felsorolja a megszakításokat és kivételeket az IDT-bejegyzésekkel és a megfelelő vektorokkal. A 0–8, 10–14 és 16–19 vektorok az előre meghatározott megszakítások és kivételek. A 32-től 255-ig terjedő vektorok a szoftver által meghatározott megszakításokra (felhasználó) vonatkoznak, amelyek vagy szoftveres megszakításokra vagy maszkolható hardvermegszakításokra vonatkoznak.

Amikor a processzor megszakítást vagy kivételt észlel, a következő műveletek egyikét teszi:

  • Implicit hívás végrehajtása egy kezelő eljáráshoz
  • Implicit hívás végrehajtása egy kezelői feladathoz

6.4 A 64 bites ARM számítógép-architektúra alapjai

Az ARM architektúrák a RISC processzorok családját határozzák meg, amelyek számos alkalmazásban használhatók. Az ARM egy betöltési/tárolási architektúra, amely megköveteli, hogy az adatokat a memóriából egy regiszterbe töltsék be, mielőtt bármilyen feldolgozás, például ALU (Aritmetikai logikai egység) művelet végbemenne vele. A következő utasítás az eredményt visszatárolja a memóriába. Bár ez visszalépésnek tűnhet az x86 és x64 architektúrákhoz képest, amelyek közvetlenül a memóriában lévő operandusokon működnek egyetlen utasításban (természetesen processzorregiszterek használatával), a betöltés/tárolás megközelítés a gyakorlatban több egymást követő műveletet tesz lehetővé. nagy sebességgel kell végrehajtani egy operanduson, miután az betöltődött a sok processzorregiszter valamelyikébe. Az ARM processzoroknak lehetőségük van kis vagy nagy végkifejletre. Az alapértelmezett ARM 64 beállítás a little-endian, amely az operációs rendszerek által általánosan használt konfiguráció. A 64 bites ARM architektúra modern, és a 32 bites ARM architektúrát váltja fel.

jegyzet : A 64 bites ARM µP minden utasítása 4 bájt (32 bit) hosszú.

6.41 A 64 bites ARM regiszterkészlet
A 64 bites ARM µP-hez 31 általános rendeltetésű 64 bites regiszter létezik. Az alábbi diagram az általános célú regisztereket és néhány fontos regisztert mutatja:


4.11.1. ábra 64 bites általános cél és néhány fontos regiszter

Az általános célú regiszterek neve X0-tól X30-ig terjed. Az egyes regiszterek első 32 bites részét W0-tól W30-ig jelöljük. Ha a 32 bit és a 64 bit közötti különbséget nem hangsúlyozzák, az „R” előtagot használjuk. Például az R14 a W14-re vagy az X14-re vonatkozik.

A 6502 µP 16 bites programszámlálóval rendelkezik, és képes megszólítani a 2-t 16 memória bájt helyek. A 64 bites ARM µP 64 bites programszámlálóval rendelkezik, és legfeljebb 2 64 = 1,844674407 x 1019 (valójában 18 446 744 073 709 551 616) memóriabájt helyek. A programszámláló tartalmazza a következő végrehajtandó utasítás címét. Az ARM64 vagy AArch64 utasításának hossza jellemzően négy bájt. A processzor automatikusan néggyel növeli ezt a regisztert, miután minden egyes utasítást lekér a memóriából.

A Stack Pointer regiszter vagy SP nem szerepel a 31 általános célú regiszter között. Bármely architektúra veremmutatója a memória utolsó verembejegyzésére mutat. Az ARM-64 esetében a köteg lefelé növekszik.

A 6502 µP 8 bites processzorállapot-regiszterrel rendelkezik. Az ARM64 megfelelőjét PSTATE regiszternek nevezik. Ez a regiszter tárolja azokat a jelzőket, amelyeket a műveletek eredményéhez és a processzor vezérléséhez használunk (µP). 32 bit széles. A következő táblázat tartalmazza a PSTATE regiszterben gyakran használt bitek nevét, indexét és jelentését:

6.41.1. táblázat
Leggyakrabban használt PSTATE zászlók (bitek)
Szimbólum Bit Célja
M 0-3 Mód: Az aktuális végrehajtási jogosultsági szint (USR, SVC és így tovább).
T 4 Thumb: Akkor van beállítva, ha a T32 (Thumb) utasításkészlet aktív. Ha üres, akkor az ARM utasításkészlet aktív. A felhasználói kód beállíthatja és törölheti ezt a bitet.
ÉS 9 Endianness: Ennek a bitnek a beállítása engedélyezi a big-endian módot. Ha világos, a kis végű mód aktív. Az alapértelmezett a little-endian mód.
K 27 Kumulatív telítettség jelző: Akkor van beállítva, ha egy műveletsorozat egy pontján túlcsordulás vagy telítettség lép fel.
BAN BEN 28 Túlcsordulás jelző: Akkor van beállítva, ha a művelet előjeles túlcsordulást eredményezett.
C 29 Carry flag: Azt jelzi, hogy az összeadás átvitelt vagy a kivonás kölcsönzést eredményezett.
VAL VEL 30 Nulla zászló: Akkor van beállítva, ha egy művelet eredménye nulla.
N 31 Negatív zászló: Akkor van beállítva, ha egy művelet eredménye negatív.

Az ARM-64 µP számos más regiszterrel rendelkezik.

SIMD
A SIMD a Single Instruction, Multiple Data rövidítése. Ez azt jelenti, hogy egy assembly nyelvű utasítás több adatra is hathat egyidejűleg egy mikroprocesszorban. A SIMD és a lebegőpontos műveletekhez harminckét 128 bit széles regiszter létezik.

6.42 Memória-leképezés
A RAM és a DRAM egyaránt Random Access memória. A DRAM lassabb, mint a RAM. A DRAM olcsóbb, mint a RAM. Ha több mint 32 gigabájt (GB) folyamatos DRAM van a memóriában, több memóriakezelési probléma lesz: 32 GB = 32 x 1024 x 1024 x 1024 bájt. A 32 GB-nál jóval nagyobb teljes memóriaterület esetén a 32 GB feletti DRAM-ot RAM-okkal kell tarkítani a jobb memóriakezelés érdekében. Az ARM-64 memóriatérkép megértéséhez először meg kell értenie a 32 bites ARM központi feldolgozó egység (CPU) 4 GB-os memóriatérképét. A CPU jelentése µP. Egy 32 bites számítógép esetében a memória címezhető területe legfeljebb 2 32 = 4 x 2 10 x 2 10 x 2 10 = 4 x 1024 x 1024 x 1024 = 4 294 967 296 = 4 GB.

32 bites ARM memóriatérkép
A 32 bites ARM memóriatérképe a következő:

Egy 32 bites számítógép esetében a teljes memória maximális mérete 4 GB. A 0 GB-os címtől az 1 GB-os címig a ROM operációs rendszer, a RAM és az I/O hely. A ROM OS, RAM és I/O címek elgondolása hasonló a Commodore-64 helyzetéhez egy lehetséges 6502-es CPU-val. A Commodore-64 operációs rendszer ROM-ja a memóriaterület legfelső végén található. A ROM OS itt sokkal nagyobb, mint a Commodore-64-é, és a teljes memóriacímtér elején található. Más modern számítógépekkel összehasonlítva a ROM operációs rendszer itt teljes, abban az értelemben, hogy összehasonlítható a merevlemezükön lévő operációs rendszer mennyiségével. Két fő oka van annak, hogy az operációs rendszer a ROM integrált áramkörökben legyen: 1) Az ARM CPU-kat többnyire kis eszközökben, például okostelefonokban használják. Sok merevlemez nagyobb, mint az okostelefonok és más kis eszközök, 2) a biztonság kedvéért. Ha az operációs rendszer csak olvasható memóriában van, azt a hackerek nem sérthetik meg (a részeket nem írhatják felül). A RAM és a bemeneti/kimeneti szekciók is nagyon nagyok a Commodore-64-hez képest.

Ha a tápellátást a 32 bites ROM operációs rendszerrel kapcsolják be, az operációs rendszernek a 0x00000000 címen vagy a 0xFFFF0000 címen kell indulnia (a rendszerindítás onnan), ha a HiVEC engedélyezve van. Tehát, amikor a visszaállítási fázis után bekapcsolják a tápfeszültséget, a CPU hardvere 0x00000000 vagy 0xFFFF0000 értéket tölt be a programszámlálóba. A „0x” előtag hexadecimálist jelent. Az ARMv8 64 bites CPU-k rendszerindítási címe egy meghatározott megvalósítás. A szerző azonban azt tanácsolja a számítógépes mérnöknek, hogy a visszamenőleges kompatibilitás érdekében kezdje 0x00000000 vagy 0xFFFF0000 értékkel.

1 GB-tól 2 GB-ig a leképezett bemenet/kimenet. Különbség van a leképezett I/O és a csak I/O között, amelyek 0 GB és 1 GB között találhatók. Az I/O-nál minden port címe rögzített, mint a Commodore-64 esetében. Leképezett I/O esetén az egyes portok címe nem feltétlenül azonos a számítógép minden egyes műveletéhez (dinamikus).

2 GB-tól 4 GB-ig a DRAM. Ez az elvárt (vagy szokásos) RAM. A DRAM a Dynamic RAM rövidítése, nem a számítógép működése közbeni címváltozás, hanem abban az értelemben, hogy a fizikai RAM minden egyes cellájának értékét minden órajel impulzusnál frissíteni kell.

jegyzet :

  • 0x0000,0000 és 0x0000 között az FFFF az operációs rendszer ROM.
  • 0x0001,0000-től 0x3FFF,FFFF-ig lehet több ROM, aztán RAM, majd némi I/O.
  • 0x4000 0000 és 0x7FFF,FFFF között további I/O és/vagy leképezett I/O megengedett.
  • 0x8000 0000-től 0xFFFF-ig az FFFF a várt DRAM.

Ezek azt jelentik, hogy a várható DRAM-nak a gyakorlatban nem kell a 2 GB-os memória határán kezdődnie. Miért kellene a programozónak tiszteletben tartania az ideális határokat, ha nincs elég fizikai RAM-bank az alaplapra? Ennek az az oka, hogy az ügyfélnek nincs elég pénze az összes RAM bankhoz.

36 bites ARM memóriatérkép
A 64 bites ARM számítógépeknél mind a 32 bit a teljes memória címzésére szolgál. Egy 64 bites ARM számítógépnél az első 36 bit használható a teljes memória címezésére, ami ebben az esetben 2 36 = 68 719 476 736 = 64 GB. Ez már sok emlék. A mai számítógépeknek nincs szükségük ekkora memóriára. Ez még nem éri el a 64 bites memória maximális tartományát. Az ARM CPU 36 bites memóriatérképe a következő:

A 0 GB-os címtől a 4 GB-os címig a 32 bites memóriatérkép. A „Fenntartva” azt jelenti, hogy nincs használatban, és későbbi felhasználásra megőrződik. Nem kell fizikai memóriabankoknak lennie, amelyek az alaplapra vannak csatlakoztatva erre a helyre. Itt a DRAM és a leképezett I/O jelentése ugyanaz, mint a 32 bites memórialeképezésnél.

A gyakorlatban a következő helyzet áll fenn:

  • 0x1 0000 0000 – 0x3 FFFF FFFF; fenntartott. 12 GB címterület van fenntartva későbbi használatra.
  • 0x4 0000 0000 – 0x7 FFFF FFFF; leképezett I/O. 16 GB címterület áll rendelkezésre a dinamikusan leképezett I/O-hoz.
  • 0x8 0000 0000 – 0x8 7FFF FFFF FFFF; Lyuk vagy DRAM. 2 GB címterület a következők egyikét tartalmazhatja:
    • Lyuk a DRAM-eszköz particionálásának engedélyezéséhez (a következő fejezetben leírtak szerint).
    • DRAM.
  • 0x8 8000 0000 – 0xF FFFF FFFF; DRAM. 30 GB címterület a DRAM számára.

Ez a memóriatérkép a 32 bites címleképezés szuperkészlete, a többletterület 50% DRAM-ként (1/2) van felosztva, egy opcionális lyukkal és 25% leképezett I/O-területtel és fenntartott területtel (1/4). ). A fennmaradó 25% (1/4) a 32 bites memórialeképezés ½ + ¼ + ¼ = 1.

jegyzet : 32 bitről 360 bitre 4 bit hozzáadását jelenti a 36 bit legjelentősebb oldalához.

40 bites memóriatérkép
A 40 bites címtérkép a 36 bites címleképezés szuperkészlete, és ugyanazt a mintát követi: 50% DRAM egy opcionális lyukból, 25% leképezett I/O terület és fenntartott terület, valamint a többi 25% hely az előző memóriatérkép számára (36 bites). A memóriatérkép diagramja a következő:

A lyuk mérete 544 – 512 = 32 GB. A gyakorlatban a következő helyzet áll fenn:

  • 0x10 0000 0000 – 0x3F FFFF FFFF; fenntartott. 192 GB címterület van fenntartva későbbi használatra.
  • 0x40 0000 0000 – 0x7F FFFF FFFF; feltérképezve. I/O 256 GB címterület áll rendelkezésre a dinamikusan leképezett I/O-hoz.
  • 0x80 0000 0000 – 0x87 FFFF FFFF; lyuk vagy DRAM. A 32 GB-os címterület a következők egyikét tartalmazhatja:
    • Lyuk a DRAM-eszköz particionálásának engedélyezéséhez (a következő megbeszélés szerint)
    • DRAM
  • 0x88 0000 0000 – 0xFF FFFF FFFF; DRAM. 480 GB címterület a DRAM számára.

jegyzet : 36 bitről 40 bitre 4 bit hozzáadását jelenti a 36 bit legjelentősebb oldalához.

DRAM lyuk
A 32 biten túli memóriatérképen ez vagy egy DRAM-lyuk, vagy a DRAM folytatása felülről. Ha lyukról van szó, azt a következőképpen kell értékelni: A DRAM-lyuk lehetőséget biztosít egy nagy DRAM-eszköz több címtartományra történő particionálására. Az opcionális DRAM-lyuk a magasabb DRAM-címhatár elején javasolt. Ez egyszerűsített dekódolási sémát tesz lehetővé, amikor egy nagy kapacitású DRAM-eszközt az alacsonyabb, fizikailag címzett régióban particionál.

Például egy 64 GB-os DRAM-rész három régióra van osztva, és a címeltolásokat egyszerű kivonással hajtják végre a magas sorrendű címbitekben, az alábbiak szerint:

6.42.1. táblázat
Példa 64 GB DRAM-os particionálásra furatokkal
Fizikai címek SoC-ben Offset Belső DRAM cím
2 GByte (32 bites térkép) 0x00 8000 0000 – 0x00 FFFF FFFF -0x00 8000 0000 0x00 0000 0000 – 0x00 7FFF FFF
30 GByte (36 bites térkép) 0x08 8000 0000 – 0x0F FFFF FFFF -0x08 0000 0000 0x00 8000 0000 – 0x07 FFFF FFFF
32 GByte (40 bites térkép) 0x88 0000 0000 – 0x8F FFFF FFFF -0x80 0000 0000 0x08 0000 0000 – 0x0F FFFF FFFF

Javasolt 44 bites és 48 bites címzett memóriatérképek ARM CPU-khoz
Tételezzük fel, hogy a személyi számítógép 1024 GB (= 1 TB) memóriával rendelkezik; ez túl sok memória. Így a 44 bites és 48 bites címzett memóriatérképek ARM CPU-khoz 16 TB-hoz, illetve 256 TB-hoz csak javaslatok a jövőbeni számítógépes igényekhez. Valójában ezek az ARM CPU-kra vonatkozó javaslatok a memória arány szerinti felosztását követik, mint az előző memórialeképezések. Vagyis: 50% DRAM opcionális lyukkal, 25% leképezett I/O terület és lefoglalt terület, a többi 25% hely pedig az előző memóriatérképhez.

Az 52-bites, 56-bites, 60-bites és 64-bites címzett memórialeképezéseket a távoli jövőben még javasolni kell az ARM 64 bitekhez. Ha a tudósok akkor még hasznosnak találják a teljes memóriaterület 50:25:25 arányú felosztását, akkor fenntartják az arányt.

jegyzet : A SoC a System-on-Chip rövidítése, amely az µP chipben lévő áramkörökre utal, amelyek egyébként nem lettek volna ott.

Az SRAM vagy a statikus véletlen hozzáférésű memória gyorsabb, mint a hagyományos DRAM, de több szilícium területet igényel. Az SRAM nem igényel frissítést. Az olvasó el tudja képzelni a RAM-ot SRAM-ként.

6.43 Összeállítási nyelvi címzési módok az ARM 64-hez
Az ARM egy betöltés/tárolás architektúra, amely megköveteli, hogy az adatokat a memóriából a processzorregiszterbe töltsék be, mielőtt bármilyen feldolgozás, például aritmetikai logikai művelet végbemenne vele. A következő utasítás az eredményt visszatárolja a memóriába. Bár ez visszalépésnek tűnhet az x86-hoz és az azt követő x64 architektúrákhoz képest, amelyek közvetlenül a memóriában lévő operandusokon működnek egyetlen utasítással, a gyakorlatban a betöltés/tárolás megközelítés lehetővé teszi több egymás utáni művelet nagy sebességű végrehajtását. egy operandus, miután betöltődik a sok processzorregiszter egyikébe.

Az ARM assembly nyelv formátuma hasonlóságokat és különbségeket mutat az x64 (x86) sorozattal.

  • Offset : Előjeles konstans hozzáadható az alapregiszterhez. Az eltolás az utasítás részeként kerül beírásra. Például: ldr x0, [rx, #10] betölti az r0-t az r1+10 címen lévő szóval.
  • Regisztráció : A regiszterben tárolt előjel nélküli növekmény hozzáadható vagy kivonható az alapregiszter értékéből. Például: ldr r0, [x1, x2] betölti az r0-t az x1+x2 címen lévő szóval. Bármelyik regiszter felfogható alapregiszternek.
  • Méretezett regiszter : A regiszterben lévő növekményt egy meghatározott számú bitpozícióval balra vagy jobbra tolják el, mielőtt hozzáadják vagy kivonják az alapregiszter értékéből. Például: ldr x0, [x1, x2, lsl #3] betölti az r0-t a szóval az r1+(r2×8) címen. Az eltolás lehet logikai balra vagy jobbra eltolás (lsl vagy lsr), amely nulla bitet szúr be a megüresedett bitpozíciókba, vagy aritmetikai jobbra eltolás (asr), amely megismétli az előjelbitet a felszabadult pozíciókban.

Ha két operandusról van szó, a cél a forrás elé kerül (balra) (ez alól van néhány kivétel). Az ARM összeállítási nyelv műveletkódjai nem érzékenyek a kis- és nagybetűkre.

Azonnali ARM64 címzési mód
Példa:

mov r0, #0xFF000000 ; Töltse be a 32 bites FF000000h értéket az r0-ba

A decimális érték 0x nélkül szerepel, de még mindig # előzi meg.

Regisztráljon közvetlenül
Példa:

mov x0, x1 ; Másolja x1-et x0-ba

Közvetett regisztráció
Példa:

str x0, [x3] ; Tárolja az x0-t az x3-ban lévő címhez

Regisztráljon Indirekt az eltolással
Példák:

ldr x0, [x1, #32] ; Az r0 betöltése az [r1+32] címen lévő értékkel; r1 az alapregiszter
str x0, [x1, #4] ; Tárolja az r0-t az [r1+4] címre; r1 az alapregiszter; a számok 10-esek

Közvetett regisztráció eltolással (előre növelve)
Példák:

ldr x0, [x1, #32]! ; Töltse be az r0-t az [r1+32]-vel, és frissítse az r1-et erre: (r1+32)
str x0, [x1, #4]! ; R0 tárolása [r1+4]-re, és r1 frissítése (r1+4)-re

Vegye figyelembe a „!” szimbólum.

Közvetett regisztráció eltolással (utólag növelve)
Példák:

ldr x0, [x1], #32 ; Az [x1] betöltése x0-ra, majd az x1 frissítése (x1+32)
str x0, [x1], #4 ; Tárolja az x0-t [x1]-re, majd frissítse az x1-et (x1+4)-re

Double Register Indirect
Az operandus címe egy alapregiszter és egy növekményregiszter összege. A regiszterneveket szögletes zárójelek veszik körül.
Példák:

ldr x0, [x1, x2] ; X0 betöltése [x1+x2]-vel
str x0, [rx, x2] ; x0 tárolása [x1+x2] között

Relatív címzési mód
Relatív címzési módban az érvényes utasítás a Programszámláló következő utasítása, plusz egy index. Az index lehet pozitív vagy negatív.
Példa:

ldr x0, [pc, #24]

Ez az X0 betöltési regisztert jelenti a PC-tartalom által mutatott szóval plusz 24.

6.44 Néhány gyakran használt utasítás az ARM 64-hez
Íme a gyakran használt utasítások:

6.45 Hurkolás

Ábra
A következő kód folyamatosan hozzáadja az X10 regiszterben lévő értéket az X9 értékhez, amíg az X8 értéke nulla lesz. Tegyük fel, hogy az összes érték egész szám. Az X8 értékét minden iterációban kivonjuk 1-gyel:

hurok:
CBZ X8, ugrás
ADD X9, X9, X10 ; az első X9 a cél, a második X9 a forrás
SUB X8, X8, #1 ; az első X8 a cél, a második X8 a forrás
B hurok
kihagyás:

A 6502 µP-hez és az X64 µP-hez hasonlóan az ARM 64 µP-ben is a címke a sor elején kezdődik. Az utasítások többi része néhány szóközzel kezdődik a sor eleje után. Az x64 és az ARM 64 esetében a címkét kettőspont és egy új sor követi. Míg a 6502-nél a címkét egy szóköz után utasítás követi. Az előző kódban az első utasítás, amely a „CBZ X8, skip” azt jelenti, hogy ha az X8-ban az érték nulla, folytassa a „skip:” címkével, kihagyva a közti utasításokat, és folytassa az alábbi utasítások többi részével. „kihagyás:”. A „B hurok” egy feltétel nélküli ugrás a „hurok” címkére. Bármilyen más címkenév használható a „hurok” helyett.

Tehát, mint a 6502 µP esetében, használja az elágazási utasításokat az ARM 64-hez való hurokhoz.

6.46 ARM 64 bemenet/kimenet
Minden ARM periféria (belső port) memórialeképezve van. Ez azt jelenti, hogy a programozói interfész memóriacímzett regiszterek (belső portok) halmaza. Egy ilyen regiszter címe egy adott memória alapcímétől való eltolás. Ez hasonló ahhoz, ahogy a 6502 végzi a bemenetet/kimenetet. Az ARM-nek nincs lehetősége külön I/O címtérre.

6.47 ARM 64 köteg
Az ARM 64-ben a 6502-höz és az x64-hez hasonló módon van egy köteg a memóriában (RAM). Az ARM64-nél azonban nincs push vagy pop opcode. Az ARM 64 stackje is lefelé növekszik. A veremmutatóban lévő cím közvetlenül a veremben elhelyezett utolsó érték utolsó bájtja után mutat.

Az ok, amiért nincs általános pop vagy push műveleti kód az ARM64-hez, az az, hogy az ARM 64 egymás utáni 16 bájtos csoportokban kezeli a veremét. Az értékek azonban egy bájtból, két bájtból, négy bájtból és 8 bájtból álló bájtcsoportokban léteznek. Tehát egy érték elhelyezhető a veremben, és a többi hely (byte-helyek) 16 bájtot pótolható álbájtokkal van kitöltve. Ennek az a hátránya, hogy pazarolja a memóriát. Jobb megoldás, ha a 16 bájtos helyet feltöltjük kisebb értékekkel, és valamilyen programozói kódot írunk, ami nyomon követi, hogy a 16 bájtos helyen lévő értékek honnan származnak (regiszterek). Ez az extra kód az értékek visszahúzásához is szükséges. Ennek alternatívája, hogy két 8 bájtos általános célú regisztert töltünk fel a különböző értékekkel, majd a két 8 bájtos regiszter tartalmát egy verembe küldjük. Itt továbbra is szükség van egy extra kódra a verembe bekerülő és a veremből kilépő kis értékek nyomon követéséhez.

A következő kód négy 4 bájtos adatot tárol a veremben:

str w0, [sp, #-4]!
str w1, [sp, #-8]!
str w2, [sp, #-12]!
str w3, [sp, #-16]!

A regiszterek első négy bájtja (w) – x0, x1, x2 és x3 – a verem 16 egymást követő byte-os helyére kerül elküldésre. Vegye figyelembe az „str” és nem a „push” használatát. Vegye figyelembe a felkiáltójelet az egyes utasítások végén. Mivel a memóriaverem lefelé növekszik, az első négy bájtos érték olyan pozícióban kezdődik, amely mínusz négy bájttal van az előző veremmutató pozíciója alatt. A többi négybájtos érték lefelé haladva következik. A következő kódszegmens a megfelelő (és sorrendben) megfelelője a négy bájt felbukkanásának:

ldr w3, [sp], #0
ldr w2, [sp], #4
ldr w1, [sp], #8
ldr w0, [sp], #12

Vegye figyelembe az ldr műveleti kód használatát a pop helyett. Azt is vegye figyelembe, hogy a felkiáltójelet itt nem használjuk.

Az X0 (8 bájt) és X1 (8 bájt) összes bájtja elküldhető a verem 16 bájtos helyére az alábbiak szerint:

stp x0, x1, [sp, #-16]! ; 8 + 8 = 16

Ebben az esetben az x2 (w2) és x3 (w3) regiszterekre nincs szükség. Az összes keresett bájt az X0 és X2 regiszterekben van. Vegye figyelembe az stp műveleti kódot a regisztertartalom párok RAM-ban való tárolására. Vegye figyelembe a felkiáltójelet is. A pop megfelelője:

ldp x0, x1, [sp], #0

Ehhez az utasításhoz nincs felkiáltójel. Vegye figyelembe az LDR műveleti kódot az LDP helyett, ha két egymást követő adathelyet tölt be a memóriából két µP regiszterbe. Ne feledje azt is, hogy a memóriából egy µP regiszterbe történő másolás betöltést jelent, nem szabad összetéveszteni a fájl lemezről a RAM-ba való betöltésével, a µP regiszter RAM-ba történő másolása pedig tárolást jelent.

6.48 Szubrutin
A szubrutin egy olyan kódblokk, amely végrehajt egy feladatot, opcionálisan néhány argumentum alapján, és opcionálisan eredményt ad vissza. Megállapodás szerint az R0–R3 regiszterek (négy regiszter) az argumentumok (paraméterek) átadására szolgálnak egy szubrutinnak, az R0 pedig az eredmény visszaküldésére szolgál a hívónak. A 4-nél több bemenetet igénylő szubrutin a veremet használja a további bemenetekhez. Egy szubrutin hívásához használja a hivatkozást vagy a feltételes elágazási utasítást. A link utasítás szintaxisa a következő:

BL címke

Ahol BL a műveleti kód, a címke pedig az alprogram kezdetét (címét). Ez az ág feltétel nélküli, előre vagy hátra 128 MB-on belül. A feltételes elágazási utasítás szintaxisa a következő:

B.cond címke

Ahol cond a feltétel, például eq (egyenlő) vagy ne (nem egyenlő). A következő programban van a doadd szubrutin, amely összeadja két argumentum értékét, és egy eredményt ad vissza R0-ban:

TERÜLET subout, CODE, READONLY ; Nevezze el ezt a kódblokkot
BELÉPÉS ; Jelölje meg az első végrehajtási utasítást
start MOV r0, #10 ; Állítsa be a paramétereket
MOV r1, #3
BL doadd ; Hívja az alprogramot
stop MOV r0, #0x18 ; angel_SWIreason_ReportException
LDR r1, =0x20026 ; ADP_Stopped_ApplicationExit
SVC #0x123456 ; ARM félhosting (korábban SWI)
doadd ADD r0, r0, r1 ; Szubrutin kódja
BX lr ; Visszatérés a szubrutinból
;
VÉGE ; Jelölje meg a fájl végét

Az összeadandó számok tízes 10 és decimális 3. A kód (program) első két sorát később magyarázzuk el. A következő három sor 10-et küld az R0-nak és 3-at az R1-nek, és meghívja a doadd szubrutint is. A „doadd” az a címke, amely az alprogram kezdetének címét tartalmazza.

Az alprogram mindössze két sorból áll. Az első sor hozzáadja az R 3-as tartalmát az R0 10-es tartalmához, ami lehetővé teszi a 13-as eredményt R0-ban. A második sor a BX műveleti kóddal és az LR operandussal tér vissza az alprogramból a hívó kódba.

JOBB
Az ARM 64 RET műveleti kódja továbbra is az alprogramot kezeli, de másképp működik, mint az RTS 6502-ben vagy a RET x64-en, vagy a „BX LR” kombináció az ARM 64-ben. Az ARM 64-ben a RET szintaxisa a következő:

EGYENES {Xn}

Ez az utasítás lehetőséget ad arra, hogy a program olyan szubrutinnal folytassa, amely nem a hívó szubrutin, vagy csak folytassa egy másik utasítással és az azt követő kódszegmenssel. Az Xn egy általános célú regiszter, amely tartalmazza azt a címet, amelyen a programnak folytatnia kell. Ez az utasítás feltétel nélkül elágazik. Alapértelmezés szerint az X30 tartalom, ha Xn nincs megadva.

Szabványos eljáráshívás
Ha a programozó azt akarja, hogy a kódja kölcsönhatásba lépjen valaki más által írt kóddal vagy egy fordító által előállított kóddal, a programozónak meg kell állapodnia a személlyel vagy a fordító írójával a regiszterhasználat szabályairól. Az ARM architektúra esetében ezeket a szabályokat Procedure Call Standardnak vagy PCS-nek nevezik. Ezek a két vagy három fél közötti megállapodások. A PCS a következőket határozza meg:

  • Mely µP regisztereket használják az argumentumok átadására a függvénynek (szubrutinnak)
  • Mely µP regiszterek használhatók az eredmény visszaadásához a hívást végző függvényhez, amelyet hívónak nevezünk
  • Az, hogy melyik µP regisztrálja a hívott függvényt, amelyet hívottnak neveznek, megsérülhet
  • A hívott fél melyik µP-t nem ronthatja el

6.49 Megszakítások
Az ARM processzorhoz kétféle megszakításvezérlő áramkör áll rendelkezésre:

  • Szabványos megszakításvezérlő: A megszakításkezelő meghatározza, hogy melyik eszköz igényel szervizelést azáltal, hogy beolvassa az eszköz bittérképes regiszterét a megszakításvezérlőben.
  • Vector Interrupt Controller (VIC): prioritást ad a megszakításoknak, és leegyszerűsíti annak meghatározását, hogy melyik eszköz okozta a megszakítást. Miután minden megszakításhoz társított egy prioritást és egy kezelőcímet, a VIC csak akkor ad megszakítási jelet a processzornak, ha egy új megszakítás prioritása magasabb, mint az éppen végrehajtott megszakításkezelőé.

jegyzet : A kivétel a hibára vonatkozik. A 32 bites ARM számítógép vektoros megszakításvezérlőjének részletei a következők (a 64 bit hasonló):

6.49.1. táblázat
ARM vektor kivétel/megszakítás 32 bites számítógéphez
Kivétel/megszakítás Rövid kéz Cím Magas cím
Visszaállítás VISSZAÁLLÍTÁS 0x00000000 0xffff0000
Meghatározatlan utasítás UNDEF 0x00000004 0xffff0004
Szoftver megszakítás SWI 0x00000008 0xffff0008
Előzetes letöltés megszakítása pabt 0x0000000C 0xffff000C
Az abortusz dátuma DABT 0x00000010 0xffff0010
Fenntartott 0x00000014 0xffff0014
Megszakítási kérelem IRQ 0x00000018 0xffff0018
Gyors megszakítási kérelem FIQ 0x0000001C 0xffff001C

Ez úgy néz ki, mint a 6502-es architektúra elrendezése NMI , BR , és IRQ mutatói lehetnek a nulla oldalon, és a megfelelő rutinok magasan vannak a memóriában (ROM OS). Az előző táblázat sorainak rövid leírása a következő:

VISSZAÁLLÍTÁS
Ez akkor történik, amikor a processzor bekapcsol. Inicializálja a rendszert, és beállítja a veremeket a különböző processzormódokhoz. Ez a legmagasabb prioritású kivétel. Az alaphelyzetbe állító kezelőbe való belépéskor a CPSR SVC módban van, és mind az IRQ, mind a FIQ bitek 1-re vannak állítva, elfedve az esetleges megszakításokat.

AZ ABORTOTÁS DÁTUMA
A második legmagasabb prioritás. Ez akkor fordul elő, ha érvénytelen címre próbálunk olvasni/írni, vagy rossz hozzáférési engedélyhez férünk hozzá. A Data Abort Handlerbe való belépéskor az IRQ-k le lesznek tiltva (I-bit készlet 1), és az FIQ engedélyezve lesz. Az IRQ-k el vannak takarva, de az FIQ-k maszk nélkül maradnak.

FIQ
A legmagasabb prioritású megszakítás, az IRQ és FIQ, le van tiltva, amíg az FIQ kezelésre nem kerül.

IRQ
A magas prioritású megszakítás, az IRQ-kezelő csak akkor lép be, ha nincs folyamatban lévő FIQ és adatmegszakítás.

Előzetes lekérés megszakítása
Ez hasonló az adatmegszakításhoz, de a címlehívási hiba esetén történik. A kezelőbe való belépéskor az IRQ-k le vannak tiltva, de az FIQ-k engedélyezve maradnak, és megtörténhetnek az elő-letöltés megszakítása során.

SWI
Szoftvermegszakítási (SWI) kivétel akkor fordul elő, ha az SWI utasítás végrehajtásra kerül, és a többi magasabb prioritású kivétel nincs megjelölve.

Undefined Instruction
A Undefined Instruction kivétel akkor fordul elő, ha egy olyan utasítás, amely nem szerepel az ARM vagy Thumb utasításkészletben, eléri a folyamat végrehajtási szakaszát, és a többi kivétel egyike sem lett megjelölve. Ez ugyanaz a prioritás, mint az SWI, ahogyan egyszerre megtörténhet. Ez azt jelenti, hogy a végrehajtott utasítás nem lehet egyszerre SWI utasítás és nem definiált utasítás.

ARM kivételkezelés
Kivétel esetén a következő események fordulnak elő:

  • Tárolja a CPSR-t a kivétel mód SPSR-jében.
  • A számítógép a kivétel mód LR-jében van tárolva.
  • A linkregiszter az aktuális utasítás alapján meghatározott címre van beállítva. Például: ISR esetén LR = utolsó végrehajtott utasítás + 8.
  • Frissítse a CPSR-t a kivételről.
  • Állítsa be a számítógépet a kivételkezelő címére.

6.5 Utasítások és adatok

Az adatok változókra (értékükkel ellátott címkékre), tömbökre és egyéb struktúrákra vonatkoznak, amelyek hasonlóak a tömbhöz. A karakterlánc olyan, mint egy karaktertömb. Az előző fejezetek egyikében egész számok tömbje látható. Az utasítások a műveleti kódokra és operandusaikra vonatkoznak. Egy program írható a memória egy folytatólagos részében kevert műveleti kódokkal és adatokkal. Ennek a megközelítésnek vannak hátrányai, de nem ajánlott.

A programot először az utasításokkal kell megírni, majd az adatokkal (a dátum többes száma adat). Az utasítások és az adatok közötti távolság csak néhány bájt lehet. Egy program esetében az utasítások és az adatok is egy vagy két különálló részben lehetnek a memóriában.

6.6 A Harvard építészete

Az egyik korai számítógép a Harvard Mark I (1944) nevet viseli. A szigorú Harvard architektúra egy címteret használ a programutasításokhoz és egy másik külön címteret az adatokhoz. Ez azt jelenti, hogy két különálló emlék van. Az alábbiakban az architektúra látható:


6.71. ábra: Harvard építészet

A vezérlőegység dekódolja az utasításokat. Az aritmetikai logikai egység (ALU) kombinációs logikával (kapuk) végzi az aritmetikai műveleteket. Az ALU elvégzi a logikai műveleteket is (pl. eltolás).

A 6502-es mikroprocesszornál egy utasítás először a mikroprocesszorhoz (vezérlőegységhez) megy, mielőtt a nullapont (az adatok egyes számában) a µP regiszterbe kerülne, mielőtt azok interakcióba lépnének. Ehhez legalább két óraimpulzusra van szükség, és ez nem egyidejű hozzáférés az utasításhoz és a nullaponthoz. Másrészt a Harvard architektúra egyidejű hozzáférést biztosít az utasításokhoz és adatokhoz, az utasítás és a nullapont egyszerre lép be a µP-be (opcode a vezérlőegységhez és nullapont a µP regiszterhez), ezzel legalább egy órajel impulzust elment. Ez a párhuzamosság egy formája. A párhuzamosságnak ezt a formáját a modern alaplapok hardveres gyorsítótárában használják (lásd a következő vitát).

6.7 Gyorsítótár

A gyorsítótár (RAM) egy nagy sebességű memóriaterület (a fő memória sebességéhez képest), amely ideiglenesen tárolja a programutasításokat vagy adatokat későbbi felhasználás céljából. A gyorsítótár gyorsabban működik, mint a fő memória. Általában ezeket az utasításokat vagy adatelemeket a rendszer a legutóbbi fő memóriából kéri le, és valószínűleg hamarosan újra szükség lesz rájuk. A gyorsítótár elsődleges célja, hogy megnövelje az ugyanazon fő memóriahelyek ismételt elérésének sebességét. A hatékony működés érdekében a gyorsítótárazott elemekhez való hozzáférésnek lényegesen gyorsabbnak kell lennie, mint az utasítások vagy adatok eredeti forrásának eléréséhez, amelyet Backing Store-nak nevezünk.

Ha a gyorsítótár használatban van, minden egyes fő memóriahely elérésére tett kísérlet a gyorsítótár keresésével kezdődik. Ha a kért elem jelen van, a processzor azonnal lekéri és felhasználja. Ezt gyorsítótár találatnak nevezik. Ha a gyorsítótárban végzett keresés sikertelen (gyorsítótár hiánya), az utasítást vagy adatelemet a háttértárból (főmemóriából) kell lekérni. A kért elem lekérésének folyamata során a rendszer egy másolatot hozzáad a gyorsítótárhoz egy várható közeljövőbeni felhasználás céljából.

Memóriakezelő egység
A memóriakezelő egység (MMU) egy olyan áramkör, amely az alaplap fő memóriáját és a kapcsolódó memóriaregisztereket kezeli. Régebben ez egy külön integrált áramkör volt az alaplapon; de ma már jellemzően a mikroprocesszor része. Az MMU-nak a gyorsítótárat (áramkört) is kezelnie kell, amely ma szintén a mikroprocesszor része. A gyorsítótár-áramkör korábban külön integrált áramkör volt.

Statikus RAM
A statikus RAM (SRAM) elérési ideje lényegesen gyorsabb, mint a DRAM, bár a lényegesen bonyolultabb áramkörök rovására. Az SRAM bitcellák sokkal több helyet foglalnak el az integrált áramkörön, mint egy DRAM-eszköz cellái, amelyek azonos mennyiségű adat tárolására képesek. A fő memória (RAM) jellemzően DRAM-ból (dinamikus RAM) áll.

A gyorsítótár javítja a számítógép teljesítményét, mivel az operációs rendszerek és alkalmazások által végrehajtott számos algoritmus a hivatkozási helyet mutatja. A hivatkozási hely a közelmúltban elért adatok újrafelhasználására utal. Ezt Temporal Locality-nek nevezik. Egy modern alaplapon a cache memória ugyanabban az integrált áramkörben található, mint a mikroprocesszor. A fő memória (DRAM) messze van, és a buszokon keresztül érhető el. A Referencia lokalitás térbeli lokalitásra is utal. A térbeli lokalitás a fizikai közelség miatti nagyobb adatelérési sebességhez kapcsolódik.

Általános szabály, hogy a cache memória régiók kicsik (a bájthelyek számát tekintve) a háttértárolóhoz (főmemória) képest. A cache memória eszközöket a maximális sebességre tervezték, ami általában azt jelenti, hogy bonyolultabbak és bitenként költségesebbek, mint a háttértárban használt adattárolási technológia. Korlátozott méretük miatt a gyorsítótár-memória eszközök gyorsan megtelnek. Ha a gyorsítótárban nincs elérhető hely egy új bejegyzés tárolására, egy régebbi bejegyzést el kell dobni. A gyorsítótár-vezérlő egy gyorsítótárcsere házirendet használ annak kiválasztására, hogy az új bejegyzés melyik gyorsítótár-bejegyzést írja felül.

A mikroprocesszor gyorsítótárának célja, hogy maximalizálja a gyorsítótár-találatok százalékos arányát az idő múlásával, így biztosítva a legmagasabb tartós utasítás-végrehajtási sebességet. E cél elérése érdekében a gyorsítótárazási logikának meg kell határoznia, hogy mely utasítások és adatok kerülnek a gyorsítótárba, és megőrződnek a közeljövőbeni használatra.

A processzor gyorsítótárazási logikája nem garantálja, hogy a gyorsítótárazott adatelemet valaha is újra felhasználják, miután behelyezték a gyorsítótárba.

A gyorsítótárazás logikája azon a valószínűségen alapul, hogy az időbeli (időben ismétlődő) és térbeli (térbeli) lokalitás miatt nagyon jó esély van arra, hogy a gyorsítótárazott adatokhoz a közeljövőben hozzáférjenek. A modern processzorokon való gyakorlati megvalósításokban a gyorsítótár-találatok általában a memóriaelérések 95-97 százalékánál fordulnak elő. Mivel a gyorsítótár-memória késleltetése a DRAM késleltetésének kis töredéke, a gyorsítótár magas találati aránya jelentős teljesítményjavuláshoz vezet a gyorsítótár-mentes kialakításhoz képest.

Némi párhuzamosság a gyorsítótárral
Mint korábban említettük, egy jó program a memóriában az utasításokat elválasztja az adatoktól. Egyes gyorsítótár-rendszerekben van egy gyorsítótár a processzor „bal oldalán”, és van egy másik gyorsítótár áramkör a processzor „jobb oldalán”. A bal oldali gyorsítótár egy program (vagy alkalmazás) utasításait, a jobb oldali pedig ugyanazon program (vagy alkalmazás) adatait kezeli. Ez jobb sebességnövekedéshez vezet.

6.8 Folyamatok és szálak

Mind a CISC, mind a RISC számítógépnek vannak folyamatai. A szoftveren folyamat van. A futó (végrehajtó) program egy folyamat. Az operációs rendszer saját programokkal érkezik. Amíg a számítógép működik, az operációs rendszer azon programjai is futnak, amelyek lehetővé teszik a számítógép működését. Ezek az operációs rendszer folyamatai. A felhasználó vagy a programozó saját programokat írhat. Amikor a felhasználó programja fut, az egy folyamat. Nem számít, hogy a program assembly nyelven vagy magas szintű nyelven, például C vagy C++ nyelven íródott. Minden folyamatot (felhasználói vagy operációs rendszert) egy másik folyamat, az úgynevezett „ütemező” kezel.

A szál olyan, mint egy folyamathoz tartozó részfolyamat. Egy folyamat elindulhat és szálakra bomlik, majd továbbra is egy folyamatként folytatódik. A szálak nélküli folyamatot tekinthetjük főszálnak. A folyamatokat és szálaikat ugyanaz az ütemező kezeli. Az ütemező maga egy program, ha rezidens az operációs rendszer lemezén. Amikor a memóriában fut, az ütemező egy folyamat.

6.9 Többszörös feldolgozás

A szálakat szinte folyamatokhoz hasonlóan kezelik. A többfeldolgozás azt jelenti, hogy egynél több folyamatot kell futtatni egy időben. Vannak számítógépek, amelyek csak egy mikroprocesszorral rendelkeznek. Vannak számítógépek egynél több mikroprocesszorral. Egyetlen mikroprocesszor esetén a folyamatok és/vagy szálak ugyanazt a mikroprocesszort használják interleaving (vagy időszeletelés) módon. Ez azt jelenti, hogy egy folyamat a processzort használja, és befejezés nélkül leáll. Egy másik folyamat vagy szál használja a processzort, és befejezés nélkül leáll. Ezután egy másik folyamat vagy szál használja a mikroprocesszort, és befejezés nélkül leáll. Ez addig folytatódik, amíg az ütemező által sorba helyezett összes folyamat és szál részesedést nem kap a processzorból. Ezt párhuzamos többfeldolgozásnak nevezik.

Ha egynél több mikroprocesszor van, akkor párhuzamos többfeldolgozásról van szó, szemben a párhuzamossággal. Ebben az esetben minden processzor egy adott folyamatot vagy szálat futtat, amely különbözik attól, amit a másik processzor futtat. Az ugyanazon az alaplapon lévő összes processzor párhuzamos többfeldolgozási folyamatban futtatja a különböző folyamatokat és/vagy különböző szálakat. A párhuzamos többfeldolgozási folyamatokat és szálakat továbbra is az ütemező kezeli. A párhuzamos többfeldolgozás gyorsabb, mint a párhuzamos többfeldolgozás.

Ezen a ponton az olvasó elgondolkozhat azon, hogy a párhuzamos feldolgozás miként gyorsabb, mint a párhuzamos feldolgozás. Ennek az az oka, hogy a processzorok ugyanazon a memórián és a bemeneti/kimeneti portokon osztoznak (különböző időpontokban kell használniuk). Nos, a gyorsítótár használatával az alaplap általános működése gyorsabb.

6.10 Lapozás

A memóriakezelő egység (MMU) egy olyan áramkör, amely közel van a mikroprocesszorhoz vagy a mikroprocesszor chipben. Kezeli a memóriatérképet, lapozást és egyéb memóriaproblémákat. Sem a 6502 µP, sem a Commodore-64 számítógép nem rendelkezik önmagában MMU-val (bár a Commodore-64-ben még mindig van némi memóriakezelés). A Commodore-64 lapozással kezeli a memóriát, ahol minden oldal 256 10 bájt hosszú (100 16 bájt hosszú). Nem volt kötelező, hogy lapozással kezelje a memóriát. Még mindig lehet benne egy memóriatérkép, majd olyan programok, amelyek éppen beillesztik magukat a különböző kijelölt területekre. Nos, a lapozás az egyik módja annak, hogy hatékonyan használjuk fel a memóriát anélkül, hogy sok olyan memóriaszakasszal rendelkeznénk, amelyek nem tartalmazhatnak adatokat vagy programot.

Az x86 386 számítógép architektúrát 1985-ben adták ki. A címbusz 32 bit széles. Tehát összesen 2 32 = 4 294 967 296 címtér lehetséges. Ez a címtér 1 048 576 oldalra = 1 024 KB oldalra oszlik. Ennél az oldalszámnál egy oldal 4096 bájt = 4 KB. Az alábbi táblázat az x86 32 bites architektúra fizikai címlapjait mutatja be:

6.10.1. táblázat
Fizikai címezhető oldalak az x86 architektúrához
Alap 16 cím Oldalak 10 alapcím
FFFFF000 – FFFFFFFF 1 048 575 oldal 4 294 963 200 – 4 294 967 295
FFFFE000 – FFFFEFFF 1 044 479 oldal 4 294 959 104 – 4 294 963 199
FFFFD000 – FFFFDFFF 1 040 383 oldal 4 294 955 008 – 4 294 959 103
|
|
|
|
|
|
|
|
|
00002000 – 00002FFF 2. oldal 8.192 – 12.288
00001000 – 00001FFF 1 oldal 4.096 – 8.191
00000000 – 00000FFF 0. oldal 0 – 4,095

Egy alkalmazás ma több programból áll. Egy program egy oldalnál kevesebbet (kevesebb, mint 4096), vagy két vagy több oldalt is igénybe vehet. Tehát egy alkalmazás egy vagy több oldalt foglalhat, ahol minden oldal 4096 bájt hosszú. Különböző emberek írhatnak egy jelentkezést, és mindegyik személy egy vagy több oldalhoz van rendelve.

Figyelje meg, hogy a 0. oldal 00000000H és 00000FFF között van
az 1. oldal 00001000H és 00001FFFH, a 2. oldal 00002000 H – 00002FFF H , stb. Egy 32 bites számítógép esetében két 32 bites regiszter található a processzorban a fizikai oldalcímzéshez: az egyik az alapcímhez, a másik az indexcímhez. Például a 2. oldal bájthelyeinek eléréséhez az alapcím regiszterének 00002-nek kell lennie. H ami az első 20 bit (balról) a 2. oldal kezdőcímeihez. A többi bit a 000 tartományban van H az FFF-hez H szerepelnek az „index regiszternek” nevezett regiszterben. Tehát az oldal összes bájtja elérhető az indexregiszter tartalmának 000-ról történő növelésével. H az FFF-hez H . Az indexregiszter tartalma hozzáadódik ahhoz a tartalomhoz, amely nem változik az alapregiszterben, hogy megkapja a tényleges címet. Ez az indexcímzési séma igaz a többi oldalra is.

Az assembly nyelvű program azonban nem igazán így van megírva minden oldalra. A programozó minden oldalhoz írja a kódot a 000. oldaltól kezdve H az FFF oldalra H . Mivel a különböző oldalakon lévő kódok össze vannak kapcsolva, a fordító az indexcímzést használja a különböző oldalakon lévő összes kapcsolódó cím összekapcsolásához. Például, ha feltételezzük, hogy a 0., az 1. és a 2. oldal egy alkalmazásra vonatkozik, és mindegyiknek az 555. H Az egymáshoz kapcsolódó címeket a fordító úgy fordítja le, hogy amikor 555 H a 0. oldalt kell elérni, 00000 H az alapnyilvántartásban lesz és az 555 H az indexregiszterben lesz. Amikor 555 H az 1. oldalt kell elérni, 00001 H az alapnyilvántartásban lesz és az 555 H az indexregiszterben lesz. Amikor 555 H a 2. oldalt kell elérni, 00002 H az alapregiszterben, az 555H pedig az indexregiszterben lesz. Ez azért lehetséges, mert a címek címkék (változók) segítségével azonosíthatók. A különböző programozóknak meg kell állapodniuk a különböző csatlakozási címekhez használandó címkék elnevezésében.

Oldal Virtuális memória
A lapozás, amint azt korábban leírtuk, módosítható a memória méretének növelése érdekében a „Page Virtual Memory” technikával. Feltételezve, hogy az összes fizikai memóriaoldalon, amint azt korábban leírtuk, van valami (utasítások és adatok), nem minden oldal aktív. Az aktuálisan nem aktív oldalak a merevlemezre kerülnek, és helyükre a merevlemez azon oldalai kerülnek, amelyeknek futniuk kell. Ily módon a memória mérete megnő. Ahogy a számítógép tovább működik, az inaktívvá váló oldalak felcserélődnek a merevlemezen lévő oldalakkal, amelyek továbbra is a memóriából a lemezre küldött oldalak lehetnek. Mindezt a memóriakezelő egység (MMU) végzi.

6.11 Problémák

Javasoljuk, hogy az olvasó az összes problémát egy fejezetben oldja meg, mielőtt a következő fejezetre lépne.

1) Adja meg a CISC és a RISC számítógép-architektúra hasonlóságait és különbségeit! Nevezzen meg egy-egy példát SISC és RISC számítógépekre.

2) a) Mik a következő nevei a CISC számítógépnek bitben kifejezve: byte, word, doubleword, quadword és double quadword?
b) Mi a következő neve a RISC számítógépnek bitben kifejezve: byte, halfword, word és doubleword.
c) Igen vagy nem. A duplaszó és a négyszó ugyanazt jelenti a CISC és a RISC architektúrában?

3 a) Az x64 esetén az assembly nyelvi utasítások bájtok száma mitől mennyiig terjed?
b) Az ARM 64 összes assembly nyelvi utasításának bájtok száma rögzített? Ha igen, mennyi a bájtok száma az összes utasításhoz?

4) Sorolja fel az x64-hez leggyakrabban használt assembly nyelvi utasításokat és azok jelentését.

5) Sorolja fel az ARM 64-hez leggyakrabban használt assembly nyelvi utasításokat és azok jelentését.

6) Rajzolja meg a régi Harvard Architecture számítógép felcímkézett blokkdiagramját. Magyarázza el, hogyan használják utasításait és adatszolgáltatásait a modern számítógépek gyorsítótárában.

7) Tegyen különbséget egy folyamat és egy szál között, és adja meg annak a folyamatnak a nevét, amely a legtöbb számítógépes rendszerben kezeli a folyamatokat és szálakat.

8) Röviden magyarázza el, mi az a multiprocessing.

9) a) Magyarázza el az x86 386 µP számítógép architektúrára vonatkozó lapozást.
b) Hogyan módosítható ez a lapozás, hogy növelje a teljes memória méretét?