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 bezbednost 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 funkcije za izolaciju i kontrolu virtualizovanih okruženja.
EL3 - Režim sigurnosnog monitora:
Ovo je najprivilegovaniji nivo i često se koristi za sigurno podizanje sistema i poverljiva izvršna okruženja.
EL3 može upravljati i kontrolisati pristupe između sigurnih i nesigurnih stanja (kao što su sigurno podizanje, 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. Pristup ARMv8 privilegijama pomaže u efikasnoj izolaciji različitih komponenti sistema, čime se poboljšava bezbednost 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 režimu od 32 bita koristeći imena w0 do w30.
x0
dox7
- Ovi se obično koriste kao registri za prolazak i prosleđivanje 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 poziva unutar procedure. 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 specifične potrebe platforme: Pokazivač na trenutni blok okruženja niti u Windows-u, ili pokazivač na trenutno izvršnu 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, pa 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 svaki 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 sačuvana 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, povratka 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 nule (uobičajena operacija) ili za obavljanje poređenja koristećisubs
kaosubs XZR, Xn, #10
čuvajući rezultujuće podatke nigde (uxzr
).
Registri Wn
su 32bit verzija registra Xn
.
SIMD i Registri za plutanje sa pokretnim zarezom
Pored toga, postoje još 32 registra dužine od 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 izazvanog 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 izvršenaV
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 je da procesor ne zna da li je operacija sa znakom ili ne, pa će proveriti C i V u operacijama i ukazati na prenos ako se dogodio u slučaju da je bio 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 jedan korak (
SS
): Koristi se od strane debagera za jednokorakno izvršavanje 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 funkcije prosleđuju u registre x0
do x7
. Dodatni parametri se prosleđuju na steku. Povratna vrednost se vraća u registru x0
, ili u x1
takođe ako je duža od 128 bita. Registri x19
do x30
i sp
moraju biti sačuvani prilikom 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 vraćanje sačuvanog pokazivača okvira i izlazak 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 treba da se izvrši (kao što su add
, sub
, mov
, itd.), dst
je odredišni 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 lokacije memorije 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 iz 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, a 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 lokaciji memorije na koju pokazujex1
.ldp
: Učitavanje para registara. Ova instrukcija učitava dva registra iz uzastopnih lokacija memorije. Adresa memorije se obično formira dodavanjem pomeraja vrednosti u drugom registru.Primer:
ldp x0, x1, [x2]
— Ovo učitavax0
ix1
sa lokacija memorije nax2
ix2 + 8
, redom.stp
: Čuvanje para registara. Ova instrukcija čuva dva registra na uzastopnim lokacijama memorije. Adresa memorije se obično formira dodavanjem pomeraja vrednosti u drugom registru.Primer:
stp x0, x1, [sp]
— Ovo čuvax0
ix1
na lokacijama memorije nasp
isp + 8
, redom.stp x0, x1, [sp, #16]!
— Ovo čuvax0
ix1
na lokacijama memorije 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, [pomeraj #N | RRX]
Xn1 -> Destinacija
Xn2 -> Operand 1
Xn3 | #imm -> Operand 2 (registar ili neposredno)
[pomeraj #N | RRX] -> Izvrši pomeraj ili pozovi RRX
Primer:
add x0, x1, x2
— Ovo sabira vrednosti ux1
ix2
i čuva rezultat ux0
.add x5, x5, #1, lsl #12
— Ovo je jednako 4096 (jedinica pomerena 12 puta) -> 1 0000 0000 0000 0000adds
Ovo vršiadd
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 čuva rezultat 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 sa n puta 2)
Logički pomeraj desno: Dodaj 1 na početak pomerajući ostale bitove unazad (deli sa n puta 2 kod nepotpisanog)
Aritmetički pomeraj desno: Kao
lsr
, ali umesto dodavanja 0 ako je najznačajniji bit 1, **dodaju se 1 (**deli sa n puta 2 kod potpisanog)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.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
broj rotacija udesno.Pomeraj bitova:
BFM Xd, Xn, #r
Potpisani pomeraj bitova:
SBFM Xd, Xn, #r, #s
Nepotpisani pomeraj bitova:
UBFM Xd, Xn, #r, #s
Ekstrakcija 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
Ekstraktuj četiri bita od 3. bita X2 i kopiraj ih u X1SBFIZ X1, X2, #3, #4
Proširi znak 4 bita iz X2 i umetni ih u X1 počevši od bita 3, nulirajući desne bitoveSBFX X1, X2, #3, #4
Ekstraktuje 4 bita počevši od bita 3 iz X2, proširuje znak 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
Ekstraktuje 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 nepotpisanom obliku) vrednosti kako bi se mogle izvršiti operacije sa njom:
SXTB X1, W2
Proširuje znak bajta iz W2 u X1 (W2
je polovinaX2
) da popuni 64 bitaSXTH X1, W2
Proširuje znak 16-bitnog broja iz W2 u X1 da popuni 64 bitaSXTW X1, W2
Proširuje znak bajta iz W2 u X1 da popuni 64 bitaUXTB X1, W2
Dodaje 0 (nepotpisano) bajtu iz W2 u X1 da popuni 64 bitaextr
: Ekstraktuje 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 destinacioni 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 operand. U ovom slučaju je to alias zaadds
i podržava istu sintaksu. Korisno za proveru da li jem == -n
.ccmp
: Uslovno upoređivanje, upoređivanje koje će se izvršiti samo ako je prethodno upoređivanje 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
upoređivanje).Ovo takođe može biti korišćeno kao
ccmn
(isto ali negativno, kaocmp
vscmn
).tst
: Proverava da li su vrednosti upoređivanja 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 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.<uslov>
: Uslovni skokovib.eq
: Skok ako je jednako, zasnovan na prethodnojcmp
instrukciji.Primer:
b.eq oznaka
— Ako je prethodnacmp
instrukcija pronašla dve jednake vrednosti, skoči naoznaka
.b.ne
: Skok ako nije jednako. Ova instrukcija proverava uslovne zastave (koje su postavljene prethodnom instrukcijom poređenja) i ako upoređene vrednosti nisu jednake, preskače do oznake ili adrese.Primer: Nakon
cmp x0, x1
instrukcije,b.ne label
— Ako vrednosti ux0
ix1
nisu jednake, preskače dolabel
.cbz
: Uporedi i skoči ako je nula. Ova instrukcija upoređuje registar sa nulom i ako su jednaki, preskače do oznake ili adrese.Primer:
cbz x0, label
— Ako je vrednost ux0
nula, preskače dolabel
.cbnz
: Uporedi i skoči ako nije nula. Ova instrukcija upoređuje registar sa nulom i ako nisu jednaki, preskače do oznake ili adrese.Primer:
cbnz x0, label
— Ako je vrednost ux0
različita od nule, preskače dolabel
.tbnz
: Testiranje bita i skok ako nije nulaPrimer:
tbnz x0, #8, label
tbz
: Testiranje bita i skok ako je nulaPrimer:
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čitava potpisanu 32-bitnu vrednost iz memorije i proširuje 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
: Čuva vrednost registra na lokaciji 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 ux1
.svc
: Pravi sistemski poziv. Označava "Supervizorski poziv". Kada procesor izvrši ovu instrukciju, prelazi iz korisničkog režima u režim jezgra i skače na određenu lokaciju u memoriji gde se nalazi kod za obradu sistemskog poziva jezgra.Primer:
Prolog funkcije
Sačuvajte registar veze 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 ka niže privilegovanom 32-bitnom programu.
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 specijalnog registra SPSR_ELx
na 1 kada je AArch32
procesna nit spremna za izvršenje, a ostatak SPSR_ELx
čuva AArch32
programe 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 CPSR-a. 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 može biti postavljeno 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
procesorskog moda u koji se preuzima izuzetak. Prilikom povratka iz 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 neke grupe:
Registar statusa aplikacije (APSR): Aritmetičke zastavice i pristupačne iz EL0
Registri stanja izvršenja: Ponašanje procesa (upravljano od strane OS-a).
Registar statusa aplikacije (APSR)
Zastavice
N
,Z
,C
,V
(kao i u AArch64)Zastava
Q
: Postavlja se na 1 kada se desi zasićenje celobrojnih vrednosti tokom izvršenja specijalizovane aritmetičke instrukcije. Kada se jednom postavi na1
, zadržava vrednost dok se ručno ne postavi na 0. Osim toga, ne postoji nijedna instrukcija koja implicitno proverava njenu vrednost, već se to mora uraditi čitanjem ručno.GE
(Veće ili jednako) zastave: Koriste se u SIMD (Single Instruction, Multiple Data) operacijama, poput "paralelnog sabiranja" i "paralelnog oduzimanja". Ove operacije omogućavaju obradu više 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 sabiranja 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 za prekidima (IRQ). i F je povezan sa brzim zahtevima za prekidima (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 pronaći šta se poziva.
machdep pozivi
XNU podržava još jednu vrstu poziva nazvanih zavisnih 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. Namena joj je da ubrza prelazak 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 (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
.
Osim toga, postavljanjem OBJC_HELP=1
i pozivanjem bilo kog binarnog fajla možete videti druge okoline promenljive koje biste mogli koristiti za zabeležavanje kada se određene Objc-C akcije dese.
Kada je ova funkcija pozvana, potrebno je pronaći pozvanu metodu naznačene instance, za to se vrše različite pretrage:
Izvršiti optimističku pretragu keša:
Ako je uspešno, završeno
Steći runtimeLock (čitanje)
Ako (realizovati && !cls->realized) realizovati klasu
Ako (inicijalizovati && !cls->initialized) inicijalizovati klasu
Pokušati sa kešom klase:
Ako je uspešno, završeno
Pokušati sa listom metoda klase:
Ako je pronađeno, popuniti keš i završeno
Pokušati sa kešom nadklase:
Ako je uspešno, završeno
Pokušati sa listom metoda nadklase:
Ako je pronađeno, popuniti keš i završeno
Ako (resolver) pokušati sa rešavačem metoda, i ponoviti od pretrage klase
Ako ste i dalje ovde (= sve ostalo nije uspelo) pokušati sa preusmerivačem
Shellkodovi
Za kompilaciju:
Da izvučemo bajtove:
Za novije macOS:
Last updated