Introduction to ARM64v8
Viwango vya Kigezo - EL (ARM64v8)
Katika usanifu wa ARMv8, viwango vya utekelezaji, vinavyojulikana kama Viwango vya Kigezo (ELs), vin定义 kiwango cha ruhusa na uwezo wa mazingira ya utekelezaji. Kuna viwango vinne vya kigezo, kuanzia EL0 hadi EL3, kila kimoja kikihudumia kusudi tofauti:
EL0 - Hali ya Mtumiaji:
Hiki ndicho kiwango chenye ruhusa ndogo zaidi na kinatumika kwa kutekeleza msimbo wa programu wa kawaida.
Programu zinazotembea kwenye EL0 zimejengwa mbali na kila mmoja na kutoka kwa programu za mfumo, kuimarisha usalama na utulivu.
EL1 - Hali ya Kernel ya Mfumo wa Uendeshaji:
Kerneli nyingi za mifumo ya uendeshaji zinatembea kwenye kiwango hiki.
EL1 ina ruhusa zaidi kuliko EL0 na inaweza kufikia rasilimali za mfumo, lakini kwa vizuizi fulani ili kuhakikisha uadilifu wa mfumo.
EL2 - Hali ya Hypervisor:
Kiwango hiki kinatumika kwa uhalisia. Hypervisor inayotembea kwenye EL2 inaweza kusimamia mifumo mingi ya uendeshaji (kila moja katika EL1 yake) inayotembea kwenye vifaa vya kimwili sawa.
EL2 inatoa vipengele vya kutenganisha na kudhibiti mazingira yaliyohalalishwa.
EL3 - Hali ya Msimamizi Salama:
Hiki ndicho kiwango chenye ruhusa kubwa zaidi na mara nyingi kinatumika kwa kuanzisha salama na mazingira ya utekelezaji yaliyoaminika.
EL3 inaweza kusimamia na kudhibiti ufikiaji kati ya hali salama na zisizo salama (kama vile kuanzisha salama, OS iliyoaminika, n.k.).
Matumizi ya viwango hivi yanaruhusu njia iliyopangwa na salama ya kusimamia vipengele tofauti vya mfumo, kutoka kwa programu za mtumiaji hadi programu za mfumo zenye ruhusa kubwa zaidi. Mbinu ya ARMv8 kuhusu viwango vya ruhusa inasaidia kutenganisha kwa ufanisi vipengele tofauti vya mfumo, hivyo kuimarisha usalama na uimara wa mfumo.
Register (ARM64v8)
ARM64 ina register 31 za matumizi ya jumla, zilizoandikwa x0
hadi x30
. Kila moja inaweza kuhifadhi thamani ya 64-bit (8-byte). Kwa operesheni zinazohitaji tu thamani za 32-bit, register hizo hizo zinaweza kufikiwa katika hali ya 32-bit kwa kutumia majina w0 hadi w30.
x0
hadix7
- Hizi kwa kawaida hutumiwa kama register za kujaribu na kwa kupitisha vigezo kwa subroutines.
x0
pia hubeba data ya kurudi ya kazi
x8
- Katika kernel ya Linux,x8
inatumika kama nambari ya wito wa mfumo kwa amri yasvc
. Katika macOS x16 ndiyo inayotumika!x9
hadix15
- Register za muda zaidi, mara nyingi hutumiwa kwa mabadiliko ya ndani.x16
nax17
- Intra-procedural Call Registers. Register za muda kwa thamani za papo hapo. Pia zinatumika kwa wito wa kazi zisizo za moja kwa moja na PLT (Jedwali la Uunganisho wa Utaratibu).
x16
inatumika kama nambari ya wito wa mfumo kwa amri yasvc
katika macOS.
x18
- Register ya Jukwaa. Inaweza kutumika kama register ya matumizi ya jumla, lakini kwenye majukwaa mengine, register hii imehifadhiwa kwa matumizi maalum ya jukwaa: Kielelezo cha block ya mazingira ya thread ya sasa katika Windows, au kuonyesha muundo wa kazi inayotekelezwa sasa katika kernel ya linux.x19
hadix28
- Hizi ni register za kuhifadhiwa na mpokeaji. Kazi lazima ihifadhi thamani za register hizi kwa mpokeaji wake, hivyo zinahifadhiwa kwenye stack na kurejeshwa kabla ya kurudi kwa mpokeaji.x29
- Pointer ya Frame ili kufuatilia frame ya stack. Wakati frame mpya ya stack inaundwa kwa sababu ya wito wa kazi, register yax29
inahifadhiwa kwenye stack na anwani ya frame mpya inahifadhiwa kwenye register hii.
Register hii inaweza pia kutumika kama register ya matumizi ya jumla ingawa kwa kawaida hutumiwa kama rejeleo kwa mabadiliko ya ndani.
x30
aulr
- Link register. Inashikilia anwani ya kurudi wakati amri yaBL
(Branch with Link) auBLR
(Branch with Link to Register) inatekelezwa kwa kuhifadhi thamani yapc
katika register hii.
Inaweza pia kutumika kama register nyingine yoyote.
Ikiwa kazi ya sasa inakusudia kuita kazi mpya na hivyo kuandika
lr
, itahifadhiwa kwenye stack mwanzoni, hii ni epilogue (stp x29, x30 , [sp, #-48]; mov x29, sp
-> Hifadhifp
nalr
, tengeneza nafasi na patafp
mpya) na kurejeshwa mwishoni, hii ni prologue (ldp x29, x30, [sp], #48; ret
-> Rejeshafp
nalr
na rudisha).
sp
- Pointer ya Stack, inayotumika kufuatilia kilele cha stack.
thamani ya
sp
inapaswa kudumishwa kuwa angalau quadword mwelekeo au mwelekeo wa makosa unaweza kutokea.
pc
- Program counter, ambayo inaonyesha amri inayofuata. Register hii inaweza kusasishwa tu kupitia uzalishaji wa makosa, marejesho ya makosa, na matawi. Amri pekee za kawaida zinazoweza kusoma register hii ni amri za matawi na viungo (BL, BLR) kuhifadhi anwani yapc
katikalr
(Link Register).xzr
- Zero register. Pia inaitwawzr
katika fomu yake ya register 32-bit. Inaweza kutumika kupata thamani ya sifuri kwa urahisi (operesheni ya kawaida) au kufanya kulinganisha kwa kutumiasubs
kamasubs XZR, Xn, #10
ikihifadhi data inayotokana mahali popote (katikaxzr
).
Register za Wn
ni toleo la 32bit la register Xn
.
SIMD na Register za Floating-Point
Zaidi ya hayo, kuna register nyingine 32 za urefu wa 128bit ambazo zinaweza kutumika katika operesheni za optimized single instruction multiple data (SIMD) na kwa kufanya hesabu za floating-point. Hizi zinaitwa register za Vn ingawa zinaweza pia kufanya kazi katika 64-bit, 32-bit, 16-bit na 8-bit na kisha zinaitwa Qn
, Dn
, Sn
, Hn
na Bn
.
Register za Mfumo
Kuna mamia ya register za mfumo, pia zinazoitwa register za matumizi maalum (SPRs), zinatumika kwa kuangalia na kudhibiti tabia za processors.
Zinaweza kusomwa au kuwekwa tu kwa kutumia amri maalum iliyotengwa mrs
na msr
.
Register maalum TPIDR_EL0
na TPIDDR_EL0
mara nyingi hupatikana wakati wa uhandisi wa kurudi. Kiambishi cha EL0
kinaonyesha kigezo kidogo ambacho register inaweza kufikiwa (katika kesi hii EL0 ni kiwango cha kawaida cha kigezo (ruhusa) ambacho programu za kawaida zinatembea nacho).
Mara nyingi hutumiwa kuhifadhi anwani ya msingi ya eneo la uhifadhi wa thread-local la kumbukumbu. Kwa kawaida ya kwanza inasomeka na kuandikwa kwa programu zinazotembea katika EL0, lakini ya pili inaweza kusomwa kutoka EL0 na kuandikwa kutoka EL1 (kama kernel).
mrs x0, TPIDR_EL0 ; Soma TPIDR_EL0 ndani ya x0
msr TPIDR_EL0, X0 ; Andika x0 ndani ya TPIDR_EL0
PSTATE
PSTATE ina vipengele kadhaa vya mchakato vilivyopangwa katika register maalum inayoweza kuonekana na mfumo wa uendeshaji SPSR_ELx
, X ikiwa ni kiwango cha ruhusa cha kigezo kilichosababisha (hii inaruhusu kurejesha hali ya mchakato wakati kigezo kinapomalizika).
Hizi ndizo sehemu zinazoweza kufikiwa:
Bendera za hali
N
,Z
,C
naV
:N
inamaanisha operesheni ilitoa matokeo hasiZ
inamaanisha operesheni ilitoa sifuriC
inamaanisha operesheni ilibebaV
inamaanisha operesheni ilitoa overflow iliyosainiwa:Jumla ya nambari mbili chanya inatoa matokeo hasi.
Jumla ya nambari mbili hasi inatoa matokeo chanya.
Katika utoaji, wakati nambari kubwa hasi inakatwa kutoka kwa nambari ndogo chanya (au kinyume chake), na matokeo hayawezi kuwakilishwa ndani ya upeo wa ukubwa wa bit uliopewa.
Kwa wazi processor haijui operesheni hiyo ina saini au la, hivyo itakagua C na V katika operesheni na kuonyesha ikiwa kubeba kumetokea katika kesi ilikuwa na saini au isiyo na saini.
Sio amri zote zinazosasisha bendera hizi. Baadhi kama CMP
au TST
hufanya hivyo, na nyingine ambazo zina kiambishi cha s kama ADDS
pia hufanya hivyo.
Bendera ya upana wa register wa sasa (
nRW
): Ikiwa bendera ina thamani 0, programu itakimbia katika hali ya utekelezaji ya AArch64 mara itakaporejeshwa.Kiwango cha Kigezo (
EL
): Programu ya kawaida inayotembea katika EL0 itakuwa na thamani 0Bendera ya kujiendesha (
SS
): Inatumika na debuggers kujiendesha kwa kuweka bendera ya SS kuwa 1 ndani yaSPSR_ELx
kupitia kigezo. Programu itakimbia hatua moja na kutoa kigezo cha kujiendesha.Bendera ya hali ya kigezo kisichofaa (
IL
): Inatumika kuashiria wakati programu yenye ruhusa inafanya uhamisho wa kiwango cha kigezo kisichofaa, bendera hii inawekwa kuwa 1 na processor inasababisha kigezo kisichofaa.Bendera za
DAIF
: Bendera hizi zinaruhusu programu yenye ruhusa kuchuja kigezo fulani cha nje.Ikiwa
A
ni 1 inamaanisha kuondolewa kwa asynchronic kutasababisha.I
inasanidiwa kujibu Maombi ya Interrupt ya vifaa vya nje (IRQs). na F inahusiana na Maombi ya Interrupt ya Haraka (FIRs).Bendera za uchaguzi wa pointer ya stack (
SPS
): Programu zenye ruhusa zinazotembea katika EL1 na juu zinaweza kubadilisha kati ya kutumia register yao ya pointer ya stack na ile ya mtumiaji (k.m. kati yaSP_EL1
naEL0
). Kubadilisha hii inafanywa kwa kuandika kwenye register maalum yaSPSel
. Hii haiwezi kufanywa kutoka EL0.
Mkataba wa Wito (ARM64v8)
Mkataba wa wito wa ARM64 unasisitiza kwamba vigezo vinane vya kwanza kwa kazi vinapitishwa katika register x0
hadi x7
. Vigezo vya ziada vinapitishwa kwenye stack. Thamani ya kurudi inarudishwa katika register x0
, au katika x1
pia ikiwa ni 128 bits ndefu. Register za x19
hadi x30
na sp
lazima zihifadhiwe kati ya wito wa kazi.
Wakati wa kusoma kazi katika assembly, angalia prologue na epilogue ya kazi. Prologue kwa kawaida inahusisha kuhifadhi pointer ya frame (x29
), kuweka pointer mpya ya frame, na kuandaa nafasi ya stack. Epilogue kwa kawaida inahusisha kurejesha pointer ya frame iliyohifadhiwa na kurudi kutoka kwa kazi.
Mkataba wa Wito katika Swift
Swift ina mkataba wake wa wito ambao unaweza kupatikana katika https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64
Amri za Kawaida (ARM64v8)
Amri za ARM64 kwa ujumla zina muundo opcode dst, src1, src2
, ambapo opcode
ni operesheni inayopaswa kufanywa (kama add
, sub
, mov
, n.k.), dst
ni register ya marudio ambapo matokeo yatahifadhiwa, na src1
na src2
ni register za chanzo. Thamani za papo hapo zinaweza pia kutumika badala ya register za chanzo.
mov
: Hamisha thamani kutoka register moja hadi nyingine.Mfano:
mov x0, x1
— Hii inahamisha thamani kutokax1
hadix0
.ldr
: Pakia thamani kutoka kumbukumbu hadi register.Mfano:
ldr x0, [x1]
— Hii inapakua thamani kutoka eneo la kumbukumbu lililoonyeshwa nax1
hadix0
.Njia ya Offset: Offset inayohusiana na kiashiria cha asili inaonyeshwa, kwa mfano:
ldr x2, [x1, #8]
, hii itapakia x2 thamani kutoka x1 + 8ldr x2, [x0, x1, lsl #2]
, hii itapakia x2 kitu kutoka kwenye array x0, kutoka kwenye nafasi x1 (index) * 4Njia ya Pre-indexed: Hii itatumika kufanya mahesabu kwa asili, kupata matokeo na pia kuhifadhi asili mpya katika asili.
ldr x2, [x1, #8]!
, hii itapakiax1 + 8
katikax2
na kuhifadhi katika x1 matokeo yax1 + 8
str lr, [sp, #-4]!
, Hifadhi register ya kiungo katika sp na sasisha register spNjia ya Post-index: Hii ni kama ya awali lakini anwani ya kumbukumbu inafikiwa na kisha offset inakokotwa na kuhifadhiwa.
ldr x0, [x1], #8
, pakiax1
katikax0
na sasisha x1 nax1 + 8
PC-relative addressing: Katika kesi hii anwani ya kupakia inakokotwa kulingana na register ya PC
ldr x1, =_start
, Hii itapakia anwani ambapo alama ya_start
inaanzia katika x1 inahusiana na PC ya sasa.str
: Hifadhi thamani kutoka register hadi kumbukumbu.Mfano:
str x0, [x1]
— Hii inahifadhi thamani katikax0
kwenye eneo la kumbukumbu lililoonyeshwa nax1
.ldp
: Pakia Pair ya Register. Amri hii inapakia register mbili kutoka maeneo ya kumbukumbu yanayofuatana. Anwani ya kumbukumbu kwa kawaida inaundwa kwa kuongeza offset kwa thamani katika register nyingine.Mfano:
ldp x0, x1, [x2]
— Hii inapakuax0
nax1
kutoka maeneo ya kumbukumbu katikax2
nax2 + 8
, mtawalia.stp
: Hifadhi Pair ya Register. Amri hii inahifadhi register mbili kwenye maeneo ya kumbukumbu yanayofuatana. Anwani ya kumbukumbu kwa kawaida inaundwa kwa kuongeza offset kwa thamani katika register nyingine.Mfano:
stp x0, x1, [sp]
— Hii inahifadhix0
nax1
kwenye maeneo ya kumbukumbu katikasp
nasp + 8
, mtawalia.stp x0, x1, [sp, #16]!
— Hii inahifadhix0
nax1
kwenye maeneo ya kumbukumbu katikasp+16
nasp + 24
, mtawalia, na sasishasp
nasp+16
.add
: Ongeza thamani za register mbili na uhifadhi matokeo katika register.Sintaksia: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
Xn1 -> Marudio
Xn2 -> Operandi 1
Xn3 | #imm -> Operandi 2 (register au papo hapo)
[shift #N | RRX] -> Fanya shift au piga RRX
Mfano:
add x0, x1, x2
— Hii inaongeza thamani katikax1
nax2
pamoja na kuhifadhi matokeo katikax0
.add x5, x5, #1, lsl #12
— Hii inalingana na 4096 (1 shifter mara 12) -> 1 0000 0000 0000 0000adds
Hii inafanyaadd
na inasasisha benderasub
: Punguza thamani za register mbili na uhifadhi matokeo katika register.Angalia
add
sintaksia.Mfano:
sub x0, x1, x2
— Hii inapunguza thamani katikax2
kutokax1
na kuhifadhi matokeo katikax0
.subs
Hii ni kama sub lakini inasasisha benderamul
: Weka thamani za register mbili na uhifadhi matokeo katika register.Mfano:
mul x0, x1, x2
— Hii inaongeza thamani katikax1
nax2
na kuhifadhi matokeo katikax0
.div
: Gawanya thamani ya register moja kwa nyingine na uhifadhi matokeo katika register.Mfano:
div x0, x1, x2
— Hii inagawanya thamani katikax1
kwax2
na kuhifadhi matokeo katikax0
.lsl
,lsr
,asr
,ror
,rrx
:Shift ya mantiki kushoto: Ongeza 0s kutoka mwisho ukihamisha bits nyingine mbele (ongeza kwa n-mara 2)
Shift ya mantiki kulia: Ongeza 1s mwanzoni ukihamisha bits nyingine nyuma (gawanya kwa n-mara 2 katika isiyo na saini)
Shift ya kihesabu kulia: Kama
lsr
, lakini badala ya kuongeza 0s ikiwa bit muhimu zaidi ni 1, 1s zinaongezwa (**gawanya kwa ntimes 2 katika saini)Rotate kulia: Kama
lsr
lakini chochote kinachondolewa kutoka kulia kinatolewa kushotoRotate Kulia na Kuongeza: Kama
ror
, lakini na bendera ya kubeba kama "bit muhimu zaidi". Hivyo bendera ya kubeba inahamishwa kwa bit 31 na bit iliyondolewa kwa bendera ya kubeba.bfm
: Bit Filed Move, operesheni hizi nakala bits0...n
kutoka thamani na kuziweka katika nafasim..m+n
.#s
inaonyesha nafasi ya bit ya kushoto na#r
ni kiasi cha kuhamasisha kulia.Hamisha bitfiled:
BFM Xd, Xn, #r
Hamisha Bitfield iliyosainiwa:
SBFM Xd, Xn, #r, #s
Hamisha Bitfield isiyosainiwa:
UBFM Xd, Xn, #r, #s
Kutoa na Kuingiza Bitfield: Nakala bitfield kutoka register moja na kuhamasisha kwenye register nyingine.
BFI X1, X2, #3, #4
Ingiza bits 4 kutoka X2 kutoka bit ya 3 ya X1BFXIL X1, X2, #3, #4
Toa kutoka bit ya 3 ya X2 bits nne na kuhamasisha kwenye X1SBFIZ X1, X2, #3, #4
Ongeza saini bits 4 kutoka X2 na kuhamasisha kwenye X1 kuanzia kwenye nafasi ya bit 3 ikizima bits za kuliaSBFX X1, X2, #3, #4
Inatoa bits 4 kuanzia bit 3 kutoka X2, inaongeza saini, na kuweka matokeo katika X1UBFIZ X1, X2, #3, #4
Ongeza 0s (isiyosainiwa) kwa byte kutoka W2 hadi X1 ili kujaza 64bitsUBFX X1, X2, #3, #4
Inatoa bits 4 kuanzia bit 3 kutoka X2 na kuweka matokeo yaliyoongezwa sifuri katika X1.Ongeza Saini kwa X: Ongeza saini (au ongeza tu 0s katika toleo lisilosainiwa) ya thamani ili uweze kufanya operesheni nayo:
SXTB X1, W2
Ongeza saini ya byte kutoka W2 hadi X1 (W2
ni nusu yaX2
) ili kujaza 64bitsSXTH X1, W2
Ongeza saini ya nambari ya 16bit kutoka W2 hadi X1 ili kujaza 64bitsSXTW X1, W2
Ongeza saini ya byte kutoka W2 hadi X1 ili kujaza 64bitsUXTB X1, W2
Ongeza 0s (isiyosainiwa) kwa byte kutoka W2 hadi X1 ili kujaza 64bitsextr
: Inatoa bits kutoka pair ya register iliyounganishwa.Mfano:
EXTR W3, W2, W1, #3
Hii itachanganya W1+W2 na kupata kuanzia bit 3 ya W2 hadi bit 3 ya W1 na kuhifadhi katika W3.cmp
: Linganisha register mbili na kuweka bendera za hali. Ni alias yasubs
ikiseti register ya marudio kuwa register ya sifuri. Inafaida kujua ikiwam == n
.Inasaidia sintaksia sawa na
subs
Mfano:
cmp x0, x1
— Hii inalinganisha thamani katikax0
nax1
na kuweka bendera za hali ipasavyo.cmn
: Linganishi operandi hasi. Katika kesi hii ni alias yaadds
na inasaidia sintaksia sawa. Inafaida kujua ikiwam == -n
.ccmp
: Linganisha kwa masharti, ni kulinganisha ambayo itafanywa tu ikiwa kulinganisha kwa awali ilikuwa kweli na itaseti bits za nzcv kwa usahihi.cmp x1, x2; ccmp x3, x4, 0, NE; blt _func
-> ikiwa x1 != x2 na x3 < x4, ruka kwa funcHii ni kwa sababu
ccmp
itatekelezwa tu ikiwacmp
ya awali ilikuwaNE
, ikiwa haikuwa bitsnzcv
zitawekwa kuwa 0 (ambayo haitaridhisha kulinganishablt
).Hii inaweza pia kutumika kama
ccmn
(sawa lakini hasi, kamacmp
dhidi yacmn
).tst
: Inakagua ikiwa yoyote ya thamani za kulinganisha ni 1 (inafanya kazi kama ANDS bila kuhifadhi matokeo mahali popote). Inafaida kuangalia register na thamani na kuangalia ikiwa yoyote ya bits za register iliyoonyeshwa katika thamani ni 1.Mfano:
tst X1, #7
Angalia ikiwa yoyote ya bits tatu za mwisho za X1 ni 1teq
: Operesheni ya XOR ikitenga matokeob
: Matawi yasiyo na mashartiMfano:
b myFunction
Kumbuka kwamba hii haitajaza register ya kiungo na anwani ya kurudi (sio sahihi kwa wito wa subrutine ambao unahitaji kurudi nyuma)
bl
: Tawi na kiungo, inatumika kuita subroutine. Inahifadhi anwani ya kurudi katikax30
.Mfano:
bl myFunction
— Hii inaita kazimyFunction
na kuhifadhi anwani ya kurudi katikax30
.Kumbuka kwamba hii haitajaza register ya kiungo na anwani ya kurudi (sio sahihi kwa wito wa subrutine ambao unahitaji kurudi nyuma)
blr
: Tawi na Kiungo kwa Register, inatumika kuita subroutine ambapo lengo linatolewa katika register. Inahifadhi anwani ya kurudi katikax30
. (Hii niMfano:
blr x1
— Hii inaita kazi ambayo anwani yake inapatikana katikax1
na kuhifadhi anwani ya kurudi katikax30
.ret
: Rudi kutoka subroutine, kwa kawaida ikitumia anwani katikax30
.Mfano:
ret
— Hii inarudi kutoka subroutine ya sasa ikitumia anwani ya kurudi katikax30
.b.<cond>
: Matawi ya mashartib.eq
: Tawi ikiwa sawa, kulingana na amri ya awali yacmp
.Mfano:
b.eq label
— Ikiwa amri ya awali yacmp
iligundua thamani mbili sawa, hii inaruka kwalabel
.b.ne
: Tawi ikiwa Sawa. Amri hii inakagua bendera za hali (ambazo ziliwekwa na amri ya kulinganisha ya awali), na ikiwa thamani zilizolinganishwa hazikuwa sawa, inatunga kwa lebo au anwani.Mfano: Baada ya amri ya
cmp x0, x1
,b.ne label
— Ikiwa thamani katikax0
nax1
hazikuwa sawa, hii inaruka kwalabel
.cbz
: Linganishi na Tawi kwenye Sifuri. Amri hii inalinganisha register na sifuri, na ikiwa sawa, inatunga kwa lebo au anwani.Mfano:
cbz x0, label
— Ikiwa thamani katikax0
ni sifuri, hii inaruka kwalabel
.cbnz
: Linganishi na Tawi kwenye Sio Sifuri. Amri hii inalinganisha register na sifuri, na ikiwa hazikuwa sawa, inatunga kwa lebo au anwani.Mfano:
cbnz x0, label
— Ikiwa thamani katikax0
sio sifuri, hii inaruka kwalabel
.tbnz
: Jaribu bit na tawi kwenye sio sifuriMfano:
tbnz x0, #8, label
tbz
: Jaribu bit na tawi kwenye sifuriMfano:
tbz x0, #8, label
Operesheni za kuchagua za masharti: Hizi ni operesheni ambazo tabia yake inatofautiana kulingana na bits za masharti.
csel Xd, Xn, Xm, cond
->csel X0, X1, X2, EQ
-> Ikiwa kweli, X0 = X1, ikiwa si kweli, X0 = X2csinc Xd, Xn, Xm, cond
-> Ikiwa kweli, Xd = Xn, ikiwa si kweli, Xd = Xm + 1cinc Xd, Xn, cond
-> Ikiwa kweli, Xd = Xn + 1, ikiwa si kweli, Xd = Xncsinv Xd, Xn, Xm, cond
-> Ikiwa kweli, Xd = Xn, ikiwa si kweli, Xd = NOT(Xm)cinv Xd, Xn, cond
-> Ikiwa kweli, Xd = NOT(Xn), ikiwa si kweli, Xd = Xncsneg Xd, Xn, Xm, cond
-> Ikiwa kweli, Xd = Xn, ikiwa si kweli, Xd = - Xmcneg Xd, Xn, cond
-> Ikiwa kweli, Xd = - Xn, ikiwa si kweli, Xd = Xncset Xd, Xn, Xm, cond
-> Ikiwa kweli, Xd = 1, ikiwa si kweli, Xd = 0csetm Xd, Xn, Xm, cond
-> Ikiwa kweli, Xd = <wote 1>, ikiwa si kweli, Xd = 0adrp
: Hesabu anwani ya ukurasa ya alama na uhifadhi katika register.Mfano:
adrp x0, symbol
— Hii inahesabu anwani ya ukurasa yasymbol
na kuihifadhi katikax0
.ldrsw
: Pakia thamani iliyosainiwa ya 32-bit kutoka kumbukumbu na ongeza saini hadi 64 bits.Mfano:
ldrsw x0, [x1]
— Hii inapakua thamani iliyosainiwa ya 32-bit kutoka eneo la kumbukumbu lililoonyeshwa nax1
, inaongeza saini hadi 64 bits, na kuihifadhi katikax0
.stur
: Hifadhi thamani ya register kwenye eneo la kumbukumbu, kwa kutumia offset kutoka register nyingine.Mfano:
stur x0, [x1, #4]
— Hii inahifadhi thamani katikax0
kwenye anwani ya kumbukumbu ambayo ni bytes 4 zaidi kuliko anwani iliyopo katikax1
.svc
: Fanya wito wa mfumo. Inasimama kwa "Wito wa Msimamizi". Wakati processor inatekeleza amri hii, inabadilika kutoka hali ya mtumiaji hadi hali ya kernel na kuruka kwenye eneo maalum la kumbukumbu ambapo msimbo wa kushughulikia wito wa mfumo wa kernel unapatikana.Mfano:
Prologue ya Kazi
Hifadhi register ya kiungo na pointer ya frame kwenye stack:
Weka kiashiria kipya cha fremu:
mov x29, sp
(inaweka kiashiria kipya cha fremu kwa kazi ya sasa)Panga nafasi kwenye stack kwa ajili ya mabadiliko ya ndani (ikiwa inahitajika):
sub sp, sp, <size>
(ambapo<size>
ni idadi ya bytes zinazohitajika)
Epilogue ya Kazi
Futa mabadiliko ya ndani (ikiwa yoyote ilipangwa):
add sp, sp, <size>
Rejesha kiashiria cha kiungo na kiashiria cha fremu:
Return:
ret
(inarudisha udhibiti kwa mwito kwa kutumia anwani katika register ya kiungo)
AARCH32 Hali ya Utendaji
Armv8-A inasaidia utendaji wa programu za bit 32. AArch32 inaweza kukimbia katika moja ya seti mbili za maagizo: A32
na T32
na inaweza kubadilisha kati yao kupitia interworking
.
Programu zenye mamlaka za bit 64 zinaweza kupanga utendaji wa programu za bit 32 kwa kutekeleza uhamisho wa kiwango cha kipekee kwa bit 32 zenye mamlaka ya chini.
Kumbuka kwamba mpito kutoka bit 64 hadi bit 32 unafanyika kwa kupunguza kiwango cha kipekee (kwa mfano, programu ya bit 64 katika EL1 ikichochea programu katika EL0). Hii inafanywa kwa kuweka bit 4 ya SPSR_ELx
register maalum kuwa 1 wakati mchakato wa AArch32
uko tayari kutekelezwa na sehemu nyingine ya SPSR_ELx
inahifadhi AArch32
programu CPSR. Kisha, mchakato wenye mamlaka unaita ERET
maagizo ili processor ipitie AArch32
kuingia katika A32 au T32 kulingana na CPSR**.**
interworking
inafanyika kwa kutumia bit J na T za CPSR. J=0
na T=0
inamaanisha A32
na J=0
na T=1
inamaanisha T32. Hii kimsingi inamaanisha kuweka bit ya chini zaidi kuwa 1 kuashiria kwamba seti ya maagizo ni T32.
Hii imewekwa wakati wa maagizo ya tawi la interworking, lakini inaweza pia kuwekwa moja kwa moja na maagizo mengine wakati PC imewekwa kama register ya marudio. Mfano:
Mfano mwingine:
Registers
Kuna register 16 za 32-bit (r0-r15). Kuanzia r0 hadi r14 zinaweza kutumika kwa operesheni yoyote, hata hivyo baadhi yao mara nyingi huhifadhiwa:
r15
: Program counter (daima). Inashikilia anwani ya amri inayofuata. Katika A32 sasa + 8, katika T32, sasa + 4.r11
: Frame Pointerr12
: Intra-procedural call registerr13
: Stack Pointerr14
: Link Register
Zaidi ya hayo, register zinaakibishwa katika banked registries
. Hizi ni sehemu zinazohifadhi thamani za register zinazoruhusu kufanya fast context switching katika usimamizi wa makosa na operesheni zenye mamlaka ili kuepuka hitaji la kuhifadhi na kurejesha register kila wakati.
Hii inafanywa kwa kuhifadhi hali ya processor kutoka CPSR
hadi SPSR
ya hali ya processor ambayo kosa limechukuliwa. Wakati kosa linaporudi, CPSR
inarejeshwa kutoka SPSR
.
CPSR - Current Program Status Register
Katika AArch32 CPSR inafanya kazi kama PSTATE
katika AArch64 na pia inahifadhiwa katika SPSR_ELx
wakati kosa linachukuliwa ili kurejesha utekelezaji baadaye:
Sehemu zimegawanywa katika makundi kadhaa:
Application Program Status Register (APSR): Bendera za hesabu na zinazoweza kufikiwa kutoka EL0
Execution State Registers: Tabia ya mchakato (inasimamiwa na OS).
Application Program Status Register (APSR)
Bendera
N
,Z
,C
,V
(kama ilivyo katika AArch64)Bendera
Q
: Inapangwa kuwa 1 kila wakati saturation ya integer inapotokea wakati wa utekelezaji wa amri maalum ya hesabu inayoshikilia. Mara inapowekwa kuwa1
, itahifadhi thamani hiyo hadi iwekwe kwa mikono kuwa 0. Zaidi ya hayo, hakuna amri inayokagua thamani yake kwa njia isiyo ya moja kwa moja, lazima ifanyike kwa kusoma kwa mikono.Bendera
GE
(Kubwa kuliko au sawa): Inatumika katika operesheni za SIMD (Single Instruction, Multiple Data), kama vile "kuongeza kwa pamoja" na "kupunguza kwa pamoja". Operesheni hizi zinaruhusu kuchakata vidokezo vingi vya data katika amri moja.
Kwa mfano, amri UADD8
inaongeza jozi nne za bytes (kutoka kwa operandi mbili za 32-bit) kwa pamoja na kuhifadhi matokeo katika register ya 32-bit. Kisha inaweka bendera za GE
katika APSR
kulingana na matokeo haya. Kila bendera ya GE inahusiana na moja ya nyongeza za byte, ikionyesha ikiwa nyongeza ya jozi hiyo ya byte ilivuka.
Amri SEL
inatumia bendera hizi za GE kufanya vitendo vya masharti.
Execution State Registers
Bits
J
naT
:J
inapaswa kuwa 0 na ikiwaT
ni 0 seti ya amri A32 inatumika, na ikiwa ni 1, T32 inatumika.IT Block State Register (
ITSTATE
): Hizi ni bits kutoka 10-15 na 25-26. Zinahifadhi masharti ya amri ndani ya kundi lililo na prefiksiIT
.E
bit: Inaonyesha endianness.Mode and Exception Mask Bits (0-4): Zinabainisha hali ya sasa ya utekelezaji. Bit ya 5 inaonyesha ikiwa programu inatekelezwa kama 32bit (1) au 64bit (0). Nyingine 4 zinaonyesha mode ya kosa inayotumika kwa sasa (wakati kosa linapotokea na linashughulikiwa). Nambari iliyowekwa inaonyesha kipaumbele cha sasa ikiwa kosa lingine litachochewa wakati huu unashughulikiwa.
AIF
: Makosa fulani yanaweza kuzuiliwa kwa kutumia bitsA
,I
,F
. IkiwaA
ni 1 inamaanisha aborts zisizo za kawaida zitaanzishwa.I
inasanidiwa kujibu Interrupts Requests (IRQs) za vifaa vya nje. na F inahusiana na Fast Interrupt Requests (FIRs).
macOS
BSD syscalls
Angalia syscalls.master. BSD syscalls zitakuwa na x16 > 0.
Mach Traps
Angalia katika syscall_sw.c mach_trap_table
na katika mach_traps.h prototypes. Nambari ya mex ya Mach traps ni MACH_TRAP_TABLE_COUNT
= 128. Mach traps zitakuwa na x16 < 0, hivyo unahitaji kuita nambari kutoka orodha ya awali kwa minus: _kernelrpc_mach_vm_allocate_trap
ni -10
.
Unaweza pia kuangalia libsystem_kernel.dylib
katika disassembler ili kupata jinsi ya kuita hizi (na BSD) syscalls:
Kumbuka kwamba Ida na Ghidra zinaweza pia ku-decompile dylibs maalum kutoka kwenye cache kwa kupitisha tu cache.
Wakati mwingine ni rahisi kuangalia decompiled code kutoka libsystem_kernel.dylib
kuliko kuangalia source code kwa sababu code ya syscalls kadhaa (BSD na Mach) inazalishwa kupitia scripts (angalia maoni katika source code) wakati katika dylib unaweza kupata kile kinachoitwa.
machdep calls
XNU inasaidia aina nyingine ya calls inayoitwa machine dependent. Idadi ya calls hizi inategemea usanifu na wala calls au idadi hazihakikishiwi kubaki kuwa thabiti.
comm page
Hii ni ukurasa wa kumbukumbu wa mmiliki wa kernel ambao umewekwa kwenye eneo la anwani la kila mchakato wa mtumiaji. Imepangwa kufanya mpito kutoka kwa hali ya mtumiaji hadi nafasi ya kernel kuwa haraka kuliko kutumia syscalls kwa huduma za kernel ambazo zinatumika sana kwamba mpito huu ungekuwa usio na ufanisi.
Kwa mfano, wito wa gettimeofdate
unasoma thamani ya timeval
moja kwa moja kutoka kwenye comm page.
objc_msgSend
Ni kawaida sana kupata kazi hii ikitumika katika programu za Objective-C au Swift. Kazi hii inaruhusu kuita njia ya kitu cha objective-C.
Parameta (maelezo zaidi katika docs):
x0: self -> Pointer kwa mfano
x1: op -> Mchoro wa njia
x2... -> Mabaki ya hoja za njia iliyoitwa
Hivyo, ikiwa utaweka breakpoint kabla ya tawi la kazi hii, unaweza kwa urahisi kupata kile kinachoitwa katika lldb (katika mfano huu, kitu kinaita kitu kutoka NSConcreteTask
ambacho kitaendesha amri):
Kuweka mabadiliko ya mazingira NSObjCMessageLoggingEnabled=1
inawezekana kurekodi wakati kazi hii inaitwa katika faili kama /tmp/msgSends-pid
.
Zaidi ya hayo, kuweka OBJC_HELP=1
na kuita binary yoyote unaweza kuona mabadiliko mengine ya mazingira ambayo unaweza kutumia ili log wakati vitendo fulani vya Objc-C vinapotokea.
Wakati kazi hii inaitwa, inahitajika kupata njia iliyoitwa ya mfano ulioonyeshwa, kwa hili tafiti tofauti zinafanywa:
Fanya utafutaji wa cache wa matumaini:
Ikiwa ni mafanikio, imekamilika
Pata runtimeLock (kusoma)
Ikiwa (realize && !cls->realized) realize darasa
Ikiwa (initialize && !cls->initialized) initialize darasa
Jaribu cache ya darasa lenyewe:
Ikiwa ni mafanikio, imekamilika
Jaribu orodha ya mbinu za darasa:
Ikiwa imepatikana, jaza cache na umalize
Jaribu cache ya darasa la juu:
Ikiwa ni mafanikio, imekamilika
Jaribu orodha ya mbinu za darasa la juu:
Ikiwa imepatikana, jaza cache na umalize
Ikiwa (resolver) jaribu mtafutaji wa mbinu, na rudia kutoka utafutaji wa darasa
Ikiwa bado hapa (= kila kitu kingine kimefeli) jaribu forwarder
Shellcodes
Ili kukusanya:
Ili kutoa byte:
Kwa macOS mpya:
Last updated