Introduction to ARM64v8
Nivoi izuzetaka - EL (ARM64v8)
U ARMv8 arhitekturi, nivoi izvršenja, poznati kao Nivoi izuzetaka (ELs), definišu nivo privilegija i mogućnosti izvršnog okruženja. Postoje četiri nivoa izuzetaka, od EL0 do EL3, pri čemu svaki služi različitoj svrsi:
EL0 - Korisnički režim:
Ovo je nivo sa najmanje privilegija i koristi se za izvršavanje redovnog aplikativnog koda.
Aplikacije koje se izvršavaju na EL0 su izolovane jedna od druge i od sistemskog softvera, što poboljšava sigurnost i stabilnost.
EL1 - Režim jezgra operativnog sistema:
Većina jezgara operativnih sistema radi na ovom nivou.
EL1 ima više privilegija od EL0 i može pristupiti sistemskim resursima, ali uz određena ograničenja radi očuvanja integriteta sistema.
EL2 - Režim hipervizora:
Ovaj nivo se koristi za virtualizaciju. Hipervizor koji radi na EL2 može upravljati sa više operativnih sistema (svaki u svom EL1) koji se izvršavaju na istom fizičkom hardveru.
EL2 pruža funkcionalnosti za izolaciju i kontrolu virtualizovanih okruženja.
EL3 - Režim sigurnosnog monitora:
Ovo je najprivilegovaniji nivo i često se koristi za sigurno pokretanje sistema i poverljiva izvršna okruženja.
EL3 može upravljati i kontrolisati pristupe između sigurnih i nesigurnih stanja (kao što su sigurno pokretanje, poverljivi OS, itd.).
Korišćenje ovih nivoa omogućava struktuiran i siguran način upravljanja različitim aspektima sistema, od korisničkih aplikacija do najprivilegovanijeg sistemskog softvera. ARMv8 pristup nivoima privilegija pomaže u efikasnoj izolaciji različitih komponenti sistema, čime se poboljšava sigurnost i pouzdanost sistema.
Registri (ARM64v8)
ARM64 ima 31 registar opšte namene, označenih kao x0
do x30
. Svaki može čuvati vrednost od 64 bita (8 bajtova). Za operacije koje zahtevaju samo vrednosti od 32 bita, isti registri mogu se pristupiti u 32-bitnom režimu koristeći imena w0 do w30.
x0
dox7
- Ovi se obično koriste kao registri za prolazak parametara podrutinama.
x0
takođe nosi povratne podatke funkcije.
x8
- U Linux jezgru,x8
se koristi kao broj sistema poziva zasvc
instrukciju. Na macOS-u se koristi x16!x9
dox15
- Dodatni privremeni registri, često korišćeni za lokalne promenljive.x16
ix17
- Registri za unutarproceduralne pozive. Privremeni registri za neposredne vrednosti. Koriste se i za indirektne pozive funkcija i PLT (Procedure Linkage Table) stubove.
x16
se koristi kao broj sistema poziva zasvc
instrukciju na macOS-u.
x18
- Registar platforme. Može se koristiti kao registar opšte namene, ali na nekim platformama, ovaj registar je rezervisan za platformski specifične svrhe: Pokazivač na trenutni blok okruženja niti u Windows-u, ili pokazivač na trenutno izvršavajuću strukturu zadatka u jezgru Linux-a.x19
dox28
- Ovo su registri sačuvani za pozvane funkcije. Funkcija mora sačuvati vrednosti ovih registara za svog pozivaoca, tako da se čuvaju na steku i vraćaju pre povratka pozivaocu.x29
- Pokazivač okvira za praćenje okvira steka. Kada se kreira novi okvir steka jer je funkcija pozvana,x29
registar se čuva na steku i nova adresa okvira (adresasp
) se čuva u ovom registru.
Ovaj registar takođe može se koristiti kao registar opšte namene, iako se obično koristi kao referenca na lokalne promenljive.
x30
ililr
- Registar linka. Čuva adresu povratka kada se izvršiBL
(Branch with Link) iliBLR
(Branch with Link to Register) instrukcija čuvajući vrednostpc
u ovom registru.
Može se koristiti kao i bilo koji drugi registar.
Ako trenutna funkcija namerava pozvati novu funkciju i time prepisati
lr
, čuvaće je na steku na početku, ovo je epilog (stp x29, x30 , [sp, #-48]; mov x29, sp
-> Čuvanjefp
ilr
, generisanje prostora i dobijanje novogfp
) i vraćaće je na kraju, ovo je prolog (ldp x29, x30, [sp], #48; ret
-> Vraćanjefp
ilr
i povratak).
sp
- Pokazivač steka, koristi se za praćenje vrha steka.
Vrednost
sp
uvek treba da bude održavana na bar quadword poravnanju ili može doći do greške poravnanja.
pc
- Brojač programa, koji pokazuje na sledeću instrukciju. Ovaj registar se može ažurirati samo putem generisanja izuzetaka, povrataka izuzetaka i skokova. Jedine obične instrukcije koje mogu čitati ovaj registar su instrukcije skoka sa linkom (BL, BLR) za čuvanje adresepc
ulr
(Registar linka).xzr
- Registar nula. Takođe nazvanwzr
u svom obliku registra od 32 bita. Može se koristiti za lako dobijanje vrednosti nula (uobičajena operacija) ili za obavljanje poređenja koristećisubs
kaosubs XZR, Xn, #10
čuvajući rezultujuće podatke nigde (uxzr
).
Wn
registri su 32-bitna verzija Xn
registra.
SIMD i Registri za plutanje sa pokretnim zarezom
Pored toga, postoje još 32 registra dužine 128 bita koji se mogu koristiti u optimizovanim operacijama jedne instrukcije sa više podataka (SIMD) i za obavljanje aritmetike sa pokretnim zarezom. Oni se nazivaju Vn registri iako mogu raditi i u 64-bitnom, 32-bitnom, 16-bitnom i 8-bitnom režimu, tada se nazivaju Qn
, Dn
, Sn
, Hn
i Bn
.
Registri sistema
Postoje stotine sistema registara, takođe nazvanih registri specijalne namene (SPR), koji se koriste za praćenje i kontrolu ponašanja procesora.
Mogu se samo čitati ili postavljati korišćenjem posvećene specijalne instrukcije mrs
i msr
.
Specijalni registri TPIDR_EL0
i TPIDDR_EL0
često se nalaze prilikom reverznog inženjeringa. Sufiks EL0
označava minimalni izuzetak iz kojeg se registar može pristupiti (u ovom slučaju EL0 je redovni nivo izuzetka (privilegija) sa kojim se izvršavaju redovni programi).
Često se koriste za čuvanje bazne adrese regiona memorije za lokalno skladištenje niti. Obično je prvi čitljiv i zapisiv za programe koji se izvršavaju u EL0, ali drugi se može čitati iz EL0 i pisati iz EL1 (kao kernel).
mrs x0, TPIDR_EL0 ; Čitanje TPIDR_EL0 u x0
msr TPIDR_EL0, X0 ; Pisanje x0 u TPIDR_EL0
PSTATE
PSTATE sadrži nekoliko procesnih komponenti serijalizovanih u operativnom sistemu vidljiv SPSR_ELx
specijalni registar, gde je X nivo dozvole pokrenutog izuzetka (ovo omogućava vraćanje stanja procesa kada izuzetak završi).
Ovo su pristupačna polja:
Zastave uslova
N
,Z
,C
iV
:N
znači da je operacija dala negativan rezultatZ
znači da je operacija dala nuluC
znači da je operacija prenesenaV
znači da je operacija dala prekoračenje sa znakom:Zbir dva pozitivna broja daje negativan rezultat.
Zbir dva negativna broja daje pozitivan rezultat.
Pri oduzimanju, kada se od manjeg pozitivnog broja oduzme veći negativni broj (ili obrnuto), i rezultat ne može biti predstavljen unutar opsega datog veličinom bita.
Očigledno, procesor ne zna da li je operacija sa znakom ili ne, pa će proveriti C i V u operacijama i ukazati na prenos ako je bila sa znakom ili bez znaka.
Nisu sve instrukcije ažuriraju ove zastave. Neke poput CMP
ili TST
to rade, a druge koje imaju sufiks s poput ADDS
takođe to rade.
Trenutna zastava širine registra (
nRW
): Ako zastava ima vrednost 0, program će se izvršavati u AArch64 stanju izvršenja nakon nastavka.Trenutni nivo izuzetka (
EL
): Redovan program koji se izvršava u EL0 imaće vrednost 0Zastava za jedno korakovanje (
SS
): Koristi se od strane debagera za jedno korakovanje postavljanjem SS zastave na 1 unutarSPSR_ELx
putem izuzetka. Program će izvršiti korak i izdati izuzetak jednog koraka.Zastava za nevažeći izuzetak (
IL
): Koristi se za označavanje kada privilegovani softver izvrši nevažeći prenos nivoa izuzetka, ova zastava se postavlja na 1 i procesor pokreće izuzetak nevažećeg stanja.Zastave
DAIF
: Ove zastave omogućavaju privilegovanom programu selektivno maskiranje određenih spoljnih izuzetaka.Ako je
A
1 to znači da će biti pokrenuti asinhroni prekidi.I
konfiguriše odgovor na spoljne hardverske zahteve za prekidima (IRQ), a F je povezano sa brzim zahtevima za prekidima (FIR).Zastave za izbor pokazivača steka (
SPS
): Privilegovani programi koji se izvršavaju u EL1 i više mogu da prebacuju između korišćenja svog registra pokazivača steka i korisničkog modela (npr. izmeđuSP_EL1
iEL0
). Ovo prebacivanje se vrši upisivanjem u specijalni registarSPSel
. Ovo se ne može uraditi iz EL0.
Konvencija pozivanja (ARM64v8)
ARM64 konvencija pozivanja specificira da se prva osam parametara funkciji prosleđuju u registrima x0
do x7
. Dodatni parametri se prosleđuju na steku. Povratna vrednost se prosleđuje nazad u registru x0
, ili u x1
takođe ako je dužine 128 bita. Registri x19
do x30
i sp
moraju biti sačuvani tokom poziva funkcije.
Prilikom čitanja funkcije u sklopu, potražite prolog funkcije i epilog. Prolog obično uključuje čuvanje pokazivača okvira (x29
), postavljanje novog pokazivača okvira, i dodeljivanje prostora steka. Epilog obično uključuje obnavljanje sačuvanog pokazivača okvira i vraćanje iz funkcije.
Konvencija pozivanja u Swift-u
Swift ima svoju konvenciju pozivanja koja se može pronaći na https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64
Uobičajene instrukcije (ARM64v8)
ARM64 instrukcije generalno imaju format opcode dst, src1, src2
, gde je opcode
operacija koja će se izvršiti (kao što su add
, sub
, mov
, itd.), dst
je ciljni registar gde će rezultat biti smešten, a src1
i src2
su izvorni registri. Neposredne vrednosti takođe mogu biti korišćene umesto izvornih registara.
mov
: Premeštanje vrednosti iz jednog registra u drugi.Primer:
mov x0, x1
— Ovo premešta vrednost izx1
ux0
.ldr
: Učitavanje vrednosti iz memorije u registar.Primer:
ldr x0, [x1]
— Ovo učitava vrednost sa memorijske lokacije na koju pokazujex1
ux0
.Mod sa pomerajem: Pomeraj koji utiče na pokazivač je naznačen, na primer:
ldr x2, [x1, #8]
, ovo će učitati u x2 vrednost sa x1 + 8ldr x2, [x0, x1, lsl #2]
, ovo će učitati u x2 objekat iz niza x0, sa pozicije x1 (indeks) * 4Mod pre indeksa: Ovo će primeniti izračunavanja na početni, dobiti rezultat i takođe sačuvati novi početak u početku.
ldr x2, [x1, #8]!
, ovo će učitatix1 + 8
ux2
i sačuvati u x1 rezultatx1 + 8
str lr, [sp, #-4]!
, Sačuvajte registar linka u sp i ažurirajte registar spMod posle indeksa: Slično prethodnom, ali se pristupa memoriji i zatim se izračunava i čuva pomeraj.
ldr x0, [x1], #8
, učitajx1
ux0
i ažuriraj x1 sax1 + 8
Adresa relativna prema PC registru: U ovom slučaju adresa za učitavanje se računa relativno prema PC registru
ldr x1, =_start
, Ovo će učitati adresu gde počinje simbol_start
u x1 u odnosu na trenutni PC.str
: Čuvanje vrednosti iz registra u memoriju.Primer:
str x0, [x1]
— Ovo čuva vrednost izx0
na memorijskoj lokaciji na koju pokazujex1
.ldp
: Učitavanje para registara. Ova instrukcija učitava dva registra iz uzastopnih memorijskih lokacija. Adresa memorije se obično formira dodavanjem pomeraja vrednosti u drugom registru.Primer:
ldp x0, x1, [x2]
— Ovo učitavax0
ix1
sa memorijskih lokacija nax2
ix2 + 8
, redom.stp
: Čuvanje para registara. Ova instrukcija čuva dva registra na uzastopnim memorijskim lokacijama. Adresa memorije se obično formira dodavanjem pomeraja vrednosti u drugom registru.Primer:
stp x0, x1, [sp]
— Ovo čuvax0
ix1
na memorijskim lokacijama nasp
isp + 8
, redom.stp x0, x1, [sp, #16]!
— Ovo čuvax0
ix1
na memorijskim lokacijama nasp+16
isp + 24
, redom, i ažurirasp
sasp+16
.add
: Sabiranje vrednosti dva registra i smeštanje rezultata u registar.Sintaksa: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
Xn1 -> Destinacija
Xn2 -> Operand 1
Xn3 | #imm -> Operand 2 (registar ili neposredno)
[shift #N | RRX] -> Izvrši pomeraj ili pozovi RRX
Primer:
add x0, x1, x2
— Ovo dodaje vrednosti ux1
ix2
zajedno i čuva rezultat ux0
.add x5, x5, #1, lsl #12
— Ovo je jednako 4096 (jedinica pomerena 12 puta) -> 1 0000 0000 0000 0000adds
Ovo izvršavaadd
i ažurira zastavesub
: Oduzmi vrednosti dva registra i čuvaj rezultat u registru.Proveri sintaksu za
add
.Primer:
sub x0, x1, x2
— Ovo oduzima vrednost ux2
odx1
i čuva rezultat ux0
.subs
Ovo je kao sub ali ažurira zastavumul
: Množi vrednosti dva registra i čuva rezultat u registru.Primer:
mul x0, x1, x2
— Ovo množi vrednosti ux1
ix2
i čuva rezultat ux0
.div
: Deljenje vrednosti jednog registra sa drugim i čuvanje rezultata u registru.Primer:
div x0, x1, x2
— Ovo deli vrednost ux1
sax2
i čuva rezultat ux0
.lsl
,lsr
,asr
,ror
,rrx
:Logički pomeraj levo: Dodaj 0 sa kraja pomerajući ostale bitove unapred (množi n puta sa 2)
Logički pomeraj desno: Dodaj 1 sa početka pomerajući ostale bitove unazad (deli n puta sa 2 u neoznačenom obliku)
Aritmetički pomeraj desno: Kao
lsr
, ali umesto dodavanja 0 ako je najznačajniji bit 1, **dodaju se 1 (**deli n puta sa 2 u označenom obliku)Rotacija udesno: Kao
lsr
ali šta god je uklonjeno sa desne strane se dodaje na levoRotacija udesno sa proširenjem: Kao
ror
, ali sa zastavicom prenosa kao "najznačajnijim bitom". Tako da se zastavica prenosa pomera na bit 31 i uklonjeni bit na zastavicu prenosa.bfm
: Pomeraj bitova, ove operacije kopiraju bitove0...n
iz vrednosti i smeštaju ih na pozicijem..m+n
.#s
određuje najlevlji bit poziciju i#r
količinu rotacije udesno.Pomeraj bitova:
BFM Xd, Xn, #r
Pomeraj bitova sa znakom:
SBFM Xd, Xn, #r, #s
Pomeraj bitova bez znaka:
UBFM Xd, Xn, #r, #s
Izdvajanje i umetanje bitova: Kopira bitovno polje iz registra i kopira ga u drugi registar.
BFI X1, X2, #3, #4
Umetni 4 bita iz X2 od 3. bita X1BFXIL X1, X2, #3, #4
Izdvoji četiri bita od 3. bita X2 i kopiraj ih u X1SBFIZ X1, X2, #3, #4
Proširi znakom 4 bita iz X2 i umetni ih u X1 počevši od bita 3, nulirajući desne bitoveSBFX X1, X2, #3, #4
Izdvaja 4 bita počevši od bita 3 iz X2, proširuje znakom ih i smešta rezultat u X1UBFIZ X1, X2, #3, #4
Proširuje nulama 4 bita iz X2 i umetni ih u X1 počevši od bita 3, nulirajući desne bitoveUBFX X1, X2, #3, #4
Izdvaja 4 bita počevši od bita 3 iz X2 i smešta nulirani rezultat u X1.Proširi znak na X: Proširuje znak (ili dodaje samo 0 u neoznačenom obliku) vrednosti kako bi se mogle izvršiti operacije sa njom:
SXTB X1, W2
Proširuje znak bajta od W2 do X1 (W2
je polovinaX2
) da popuni 64 bitaSXTH X1, W2
Proširuje znak 16-bitnog broja od W2 do X1 da popuni 64 bitaSXTW X1, W2
Proširuje znak bajta od W2 do X1 da popuni 64 bitaUXTB X1, W2
Dodaje 0 (neoznačeno) bajtu od W2 do X1 da popuni 64 bitaextr
: Izdvaja bitove iz određenog para registara konkateniranih.Primer:
EXTR W3, W2, W1, #3
Ovo će konkatenirati W1+W2 i uzeti od bita 3 iz W2 do bita 3 iz W1 i smestiti u W3.cmp
: Uporedi dva registra i postavi uslovne zastave. To je alias zasubs
postavljajući odredišni registar na nulu. Korisno za proveru da li jem == n
.Podržava istu sintaksu kao
subs
Primer:
cmp x0, x1
— Ovo upoređuje vrednosti ux0
ix1
i postavlja uslovne zastave prema tome.cmn
: Uporedi negativno operande. U ovom slučaju je to alias zaadds
i podržava istu sintaksu. Korisno za proveru da li jem == -n
.ccmp
: Uslovno poređenje, to je poređenje koje će se izvršiti samo ako je prethodno poređenje bilo tačno i posebno će postaviti nzcv bitove.cmp x1, x2; ccmp x3, x4, 0, NE; blt _func
-> ako x1 != x2 i x3 < x4, skoči na funkcijuTo je zato što će se
ccmp
izvršiti samo ako je prethodnicmp
bioNE
, ako nije, bitovinzcv
će biti postavljeni na 0 (što neće zadovoljitiblt
poređenje).Ovo se takođe može koristiti kao
ccmn
(isto ali negativno, kaocmp
vscmn
).tst
: Proverava da li su vrednosti uporedbe oba 1 (radi kao i ANDS bez smeštanja rezultata bilo gde). Korisno je proveriti registar sa vrednošću i proveriti da li su bilo koji bitovi registra naznačeni u vrednosti 1.Primer:
tst X1, #7
Proveri da li su bilo koji od poslednja 3 bita X1 jednaki 1teq
: XOR operacija odbacivanjem rezultatab
: Bezuslovni skokPrimer:
b mojaFunkcija
Imajte na umu da ovo neće popuniti registar linka sa povratnom adresom (nije pogodno za pozive potprograma koji treba da se vrate nazad)
bl
: Skok sa linkom, koristi se za poziv potprograma. Čuva povratnu adresu ux30
.Primer:
bl mojaFunkcija
— Ovo poziva funkcijumojaFunkcija
i čuva povratnu adresu ux30
.Imajte na umu da ovo neće popuniti registar linka sa povratnom adresom (nije pogodno za pozive potprograma koji treba da se vrate nazad)
blr
: Skok sa Linkom u Registar, koristi se za poziv potprograma gde je cilj specifikovan u registru. Čuva povratnu adresu ux30
. (Ovo jePrimer:
blr x1
— Ovo poziva funkciju čija je adresa sadržana ux1
i čuva povratnu adresu ux30
.ret
: Povratak iz potprograma, obično koristeći adresu ux30
.Primer:
ret
— Ovo se vraća iz trenutnog potprograma koristeći povratnu adresu ux30
.b.<cond>
: Uslovni skokovib.eq
: Skok ako je jednako, zasnovano na prethodnojcmp
instrukciji.Primer:
b.eq oznaka
— Ako je prethodnacmp
instrukcija pronašla dve jednake vrednosti, skoči naoznaka
.b.ne
: Branch if Not Equal. Ova instrukcija proverava uslovne zastavice (koje su postavljene od strane prethodne instrukcije poređenja), i ako upoređene vrednosti nisu jednake, prelazi na oznaku ili adresu.Primer: Nakon
cmp x0, x1
instrukcije,b.ne label
— Ako vrednosti ux0
ix1
nisu jednake, prelazi nalabel
.cbz
: Uporedi i pređi na nulu. Ova instrukcija upoređuje registar sa nulom, i ako su jednaki, prelazi na oznaku ili adresu.Primer:
cbz x0, label
— Ako je vrednost ux0
nula, prelazi nalabel
.cbnz
: Uporedi i pređi na ne-nulu. Ova instrukcija upoređuje registar sa nulom, i ako nisu jednaki, prelazi na oznaku ili adresu.Primer:
cbnz x0, label
— Ako je vrednost ux0
ne-nula, prelazi nalabel
.tbnz
: Testiraj bit i pređi na ne-nuluPrimer:
tbnz x0, #8, label
tbz
: Testiraj bit i pređi na nuluPrimer:
tbz x0, #8, label
Operacije uslovnog izbora: Ovo su operacije čije ponašanje varira u zavisnosti od uslovnih bitova.
csel Xd, Xn, Xm, cond
->csel X0, X1, X2, EQ
-> Ako je tačno, X0 = X1, ako nije, X0 = X2csinc Xd, Xn, Xm, cond
-> Ako je tačno, Xd = Xn, ako nije, Xd = Xm + 1cinc Xd, Xn, cond
-> Ako je tačno, Xd = Xn + 1, ako nije, Xd = Xncsinv Xd, Xn, Xm, cond
-> Ako je tačno, Xd = Xn, ako nije, Xd = NIJE(Xm)cinv Xd, Xn, cond
-> Ako je tačno, Xd = NIJE(Xn), ako nije, Xd = Xncsneg Xd, Xn, Xm, cond
-> Ako je tačno, Xd = Xn, ako nije, Xd = - Xmcneg Xd, Xn, cond
-> Ako je tačno, Xd = - Xn, ako nije, Xd = Xncset Xd, Xn, Xm, cond
-> Ako je tačno, Xd = 1, ako nije, Xd = 0csetm Xd, Xn, Xm, cond
-> Ako je tačno, Xd = <svi 1>, ako nije, Xd = 0adrp
: Izračunava adresu stranice simbola i smešta je u registar.Primer:
adrp x0, symbol
— Ovo izračunava adresu stranicesymbol
i smešta je ux0
.ldrsw
: Učitaj potpisanu 32-bitnu vrednost iz memorije i proširi je na 64 bita.Primer:
ldrsw x0, [x1]
— Ovo učitava potpisanu 32-bitnu vrednost sa lokacije u memoriji na koju pokazujex1
, proširuje je na 64 bita i smešta je ux0
.stur
: Smešta vrednost registra na lokaciju u memoriji, koristeći pomeraj od drugog registra.Primer:
stur x0, [x1, #4]
— Ovo smešta vrednost izx0
na adresu u memoriji koja je 4 bajta veća od adrese koja se trenutno nalazi ux1
.svc
: Napravi sistemski poziv. Ovo označava "Supervizorski poziv". Kada procesor izvrši ovu instrukciju, prelazi iz režima korisnika u režim jezgra i prelazi na određenu lokaciju u memoriji gde se nalazi kod za obradu sistemskog poziva jezgra.Primer:
Prolog funkcije
Sačuvaj registar linka i pokazivač okvira na steku:
Postavite novi pokazivač okvira:
mov x29, sp
(postavlja novi pokazivač okvira za trenutnu funkciju)Alocirajte prostor na steku za lokalne promenljive (ako je potrebno):
sub sp, sp, <size>
(gde je<size>
broj bajtova potreban)
Epilog funkcije
Dealocirajte lokalne promenljive (ako su alocirane):
add sp, sp, <size>
Vratite registar veze i pokazivač okvira:
Povratak:
ret
(vraća kontrolu pozivaocu koristeći adresu u registru veze)
Stanje izvršenja AARCH32
Armv8-A podržava izvršenje 32-bitnih programa. AArch32 može raditi u jednom od dva skupa instrukcija: A32
i T32
i može prelaziti između njih putem međusobnog rada
.
Privilegovani 64-bitni programi mogu zakazati izvršenje 32-bitnih programa izvršavanjem transfera nivoa izuzetka na niže privilegovani 32-bitni program.
Napomena da se prelazak sa 64-bitnog na 32-bitni dešava sa nižim nivoom izuzetka (na primer, 64-bitni program u EL1 pokreće program u EL0). Ovo se postiže postavljanjem bita 4 od SPSR_ELx
specijalnog registra na 1 kada je AArch32
procesna nit spremna za izvršenje, a ostatak SPSR_ELx
čuva programe AArch32
CPSR. Zatim, privilegovani proces poziva instrukciju ERET
kako bi procesor prešao u AArch32
ulazeći u A32 ili T32 u zavisnosti od CPSR**.**
Međusobni rad
se dešava korišćenjem bitova J i T u CPSR. J=0
i T=0
znači A32
i J=0
i T=1
znači T32. Ovo se u osnovi prevodi na postavljanje najnižeg bita na 1 kako bi se naznačilo da je skup instrukcija T32.
Ovo se postavlja tokom instrukcija grana međusobnog rada, ali se takođe može postaviti direktno i drugim instrukcijama kada je PC postavljen kao registar odredišta. Primer:
Još jedan primer:
Registri
Postoje 16 registara od 32 bita (r0-r15). Od r0 do r14 mogu se koristiti za bilo koju operaciju, međutim neki od njih obično su rezervisani:
r15
: Brojač programa (uvek). Sadrži adresu sledeće instrukcije. U A32 trenutno + 8, u T32, trenutno + 4.r11
: Pokazivač okvirar12
: Registar za unutarproceduralne poziver13
: Pokazivač stekar14
: Registar za povezivanje
Osim toga, registri se čuvaju u bankovnim registrima
. To su mesta koja čuvaju vrednosti registara omogućavajući brzo prebacivanje konteksta u rukovanju izuzecima i privilegovanim operacijama kako bi se izbegla potreba za ručnim čuvanjem i vraćanjem registara svaki put.
Ovo se postiže čuvanjem stanja procesora od CPSR
do SPSR
režima procesora u koji se preuzima izuzetak. Prilikom povratka izuzetka, CPSR
se obnavlja iz SPSR
.
CPSR - Trenutni registar statusa programa
U AArch32, CPSR radi slično kao PSTATE
u AArch64 i takođe se čuva u SPSR_ELx
kada se preuzme izuzetak radi kasnijeg obnavljanja izvršenja:
Polja su podeljena u nekoliko grupa:
Registar statusa aplikacije (APSR): Aritmetičke zastave i pristupačne iz EL0
Registri stanja izvršenja: Ponašanje procesa (upravljano od strane OS-a).
Registar statusa aplikacije (APSR)
Zastave
N
,Z
,C
,V
(kao i u AArch64)Zastava
Q
: Postavlja se na 1 kada se desi zasićenje celog broja tokom izvršenja specijalizovane aritmetičke instrukcije zasićenja. Kada se jednom postavi na1
, zadržaće vrednost dok se ručno ne postavi na 0. Osim toga, ne postoji nijedna instrukcija koja implicitno proverava njegovu vrednost, to se mora uraditi čitanjem ručno.GE
(Veće ili jednako) zastave: Koriste se u SIMD (Jedna instrukcija, više podataka) operacijama, poput "paralelnog sabiranja" i "paralelnog oduzimanja". Ove operacije omogućavaju obradu više tačaka podataka u jednoj instrukciji.
Na primer, instrukcija UADD8
sabira četiri para bajtova (iz dva 32-bitna operanda) paralelno i čuva rezultate u 32-bitnom registru. Zatim postavlja GE
zastave u APSR
na osnovu ovih rezultata. Svaka GE zastava odgovara jednom od dodavanja bajtova, ukazujući da li je sabiranje za taj par bajtova prekoračilo.
Instrukcija SEL
koristi ove GE zastave za izvođenje uslovnih radnji.
Registri stanja izvršenja
Bitovi
J
iT
:J
treba da bude 0, a ako jeT
0 koristi se skup instrukcija A32, a ako je 1, koristi se T32.Registar stanja IT bloka (
ITSTATE
): To su bitovi od 10-15 i 25-26. Čuvaju uslove za instrukcije unutar grupe sa prefiksomIT
.Bit
E
: Označava endianness.Bitovi moda i maski izuzetka (0-4): Određuju trenutno stanje izvršenja. Peti označava da li program radi kao 32-bitni (1) ili 64-bitni (0). Ostala 4 predstavljaju trenutni korišćeni režim izuzetka (kada se desi izuzetak i kada se rukuje njime). Postavljeni broj označava trenutni prioritet u slučaju da se desi još jedan izuzetak dok se ovaj rukuje.
AIF
: Određeni izuzeci mogu biti onemogućeni korišćenjem bitovaA
,I
,F
. Ako jeA
1, to znači da će biti pokrenuti asinhroni prekidi.I
konfiguriše odgovor na spoljne hardverske zahteve prekida (IRQ). i F je povezan sa brzim zahtevima prekida (FIR).
macOS
BSD sistemski pozivi
Pogledajte syscalls.master. BSD sistemski pozivi će imati x16 > 0.
Mach zamke
Pogledajte u syscall_sw.c mach_trap_table
i u mach_traps.h prototipove. Maksimalan broj Mach zamki je MACH_TRAP_TABLE_COUNT
= 128. Mach zamke će imati x16 < 0, pa je potrebno pozvati brojeve sa prethodne liste sa minusom: _kernelrpc_mach_vm_allocate_trap
je -10
.
Takođe možete proveriti libsystem_kernel.dylib
u disassembleru da biste saznali kako pozvati ove (i BSD) sistemski pozivi:
Ponekad je lakše proveriti dekompilovani kod iz libsystem_kernel.dylib
nego proveravati izvorni kod jer je kod nekoliko sistemskih poziva (BSD i Mach) generisan putem skripti (proverite komentare u izvornom kodu), dok u dylib datoteci možete videti šta se poziva.
machdep pozivi
XNU podržava još jednu vrstu poziva nazvanu zavisnu od mašine. Broj ovih poziva zavisi od arhitekture i ni pozivi ni brojevi nisu zagarantovani da će ostati konstantni.
comm stranica
Ovo je stranica memorije vlasništvo jezgra koja je mapirana u adresni prostor svakog korisničkog procesa. Namijenjena je ubrzanju prelaska iz režima korisnika u prostor jezgra brže nego korišćenjem sistemskih poziva za jezgrene usluge koje se toliko koriste da bi taj prelazak bio veoma neefikasan.
Na primer, poziv gettimeofdate
čita vrednost timeval
direktno sa comm stranice.
objc_msgSend
Veoma je često naći ovu funkciju korišćenu u Objective-C ili Swift programima. Ova funkcija omogućava pozivanje metode objekta Objective-C.
Parametri (više informacija u dokumentaciji):
x0: self -> Pokazivač na instancu
x1: op -> Selektor metode
x2... -> Ostali argumenti pozvane metode
Dakle, ako postavite prekidnu tačku pre grananja ka ovoj funkciji, lako možete pronaći šta je pozvano u lldb-u sa (u ovom primeru objekat poziva objekat iz NSConcreteTask
koji će pokrenuti komandu):
Postavljanjem env promenljive NSObjCMessageLoggingEnabled=1
moguće je zabeležiti kada je ova funkcija pozvana u datoteci poput /tmp/msgSends-pid
.
Shellkodovi
Za kompajliranje:
Da izvučemo bajtove:
Za novije macOS:
Last updated