Introduction to ARM64v8
Επίπεδα Εξαιρέσεων - EL (ARM64v8)
Στην αρχιτεκτονική ARMv8, τα επίπεδα εκτέλεσης, γνωστά ως Επίπεδα Εξαιρέσεων (ELs), καθορίζουν το επίπεδο προνομίων και τις δυνατότητες του περιβάλλοντος εκτέλεσης. Υπάρχουν τέσσερα επίπεδα εξαιρέσεων, από EL0 έως EL3, το καθένα εξυπηρετώντας διαφορετικό σκοπό:
EL0 - Λειτουργία Χρήστη:
Αυτό είναι το επίπεδο με τα λιγότερα προνόμια και χρησιμοποιείται για την εκτέλεση κανονικού κώδικα εφαρμογών.
Οι εφαρμογές που εκτελούνται στο EL0 είναι απομονωμένες μεταξύ τους και από το λογισμικό συστήματος, βελτιώνοντας την ασφάλεια και τη σταθερότητα.
EL1 - Λειτουργικό Σύστημα Πυρήνα:
Οι περισσότεροι πυρήνες λειτουργικών συστημάτων τρέχουν σε αυτό το επίπεδο.
Το EL1 έχει περισσότερα προνόμια από το EL0 και μπορεί να έχει πρόσβαση σε πόρους συστήματος, αλλά με κάποιους περιορισμούς για να διασφαλιστεί η ακεραιότητα του συστήματος.
EL2 - Λειτουργία Υπερτροφοδοτητή:
Αυτό το επίπεδο χρησιμοποιείται για εικονικοποίηση. Ένας υπερτροφοδοτητής που τρέχει στο EL2 μπορεί να διαχειριστεί πολλά λειτουργικά συστήματα (καθένα στο δικό του EL1) που τρέχουν στον ίδιο φυσικό υλικό.
Το EL2 παρέχει χαρακτηριστικά για απομόνωση και έλεγχο των εικονικών περιβαλλόντων.
EL3 - Λειτουργία Ασφαλούς Παρακολούθησης:
Αυτό είναι το πιο προνομιούχο επίπεδο και χρησιμοποιείται συχνά για ασφαλή εκκίνηση και περιβάλλοντα εκτέλεσης που μπορεί να εμπιστευτεί.
Το EL3 μπορεί να διαχειριστεί και να ελέγξει τις προσβάσεις μεταξύ ασφαλών και μη-ασφαλών καταστάσεων (όπως ασφαλή εκκίνηση, αξιόπιστο λειτουργικό σύστημα κλπ.).
Η χρήση αυτών των επιπέδων επιτρέπει έναν δομημένο και ασφαλή τρόπο διαχείρισης διαφορετικών πτυχών του συστήματος, από εφαρμογές χρηστών έως το πιο προνομιούχο λογισμικό συστήματος. Η προσέγγιση της ARMv8 στα επίπεδα προνομίων βοηθά στην απομόνωση διαφορετικών συστατικών του συστήματος, βελτιώνοντας έτσι την ασφάλεια και την ανθεκτικότητα του συστήματος.
Καταχωρητές (ARM64v8)
Το ARM64 έχει 31 καταχωρητές γενικής χρήσης, με ετικέτες x0
έως x30
. Κάθε ένας μπορεί να αποθηκεύσει μια τιμή 64-bit (8-byte). Για λειτουργίες που απαιτούν μόνο τιμές 32-bit, οι ίδιοι καταχωρητές μπορούν να προσπελαστούν σε λειτουργία 32-bit χρησιμοποιώντας τα ονόματα w0 έως w30.
x0
έωςx7
- Αυτοί χρησιμοποιούνται συνήθως ως καταχωρητές scratch και για τη μετάδοση παραμέτρων σε υπορουτίνες.
Ο
x0
μεταφέρει επίσης τα δεδομένα επιστροφής μιας συνάρτησης.
x8
- Στον πυρήνα Linux, τοx8
χρησιμοποιείται ως ο αριθμός κλήσης συστήματος για την εντολήsvc
. Στο macOS χρησιμοποιείται το x16!x9
έωςx15
- Περισσότεροι προσωρινοί καταχωρητές, συχνά χρησιμοποιούμενοι για τοπικές μεταβλητές.x16
καιx17
- Καταχωρητές Κλήσης Εντός-Διαδικασίας. Προσωρινοί καταχωρητές για άμεσες τιμές. Χρησιμοποιούνται επίσης για άμεσες κλήσεις συναρτήσεων και στοιχεία PLT (Procedure Linkage Table).
Το
x16
χρησιμοποιείται ως ο αριθμός κλήσης συστήματος για την εντολήsvc
στο macOS.
x18
- Καταχωρητής πλατφόρμας. Μπορεί να χρησιμοποιηθεί ως καταχωρητής γενικής χρήσης, αλλά σε ορισμένες πλατφόρμες, αυτός ο καταχωρητής είναι κρατημένος για πλατφορμοεξαρτημένες χρήσεις: Δείκτης προς το τρέχον τμήμα περιβάλλοντος νήματος στα Windows, ή για να δείχνει στη δομή της τρέχουσας εργασίας στον πυρήνα του Linux.x19
έωςx28
- Αυτοί είναι καταχωρητές που αποθηκεύονται από τον καλούντα σε μια συνάρτηση, έτσι πρέπει να διατηρούνται οι τιμές τους για τον καλούντα, επομένως αποθηκεύονται στη στοίβα και ανακτώνται πριν επιστρέψουν στον καλούντα.x29
- Δείκτης Πλαισίου για να παρακολουθεί το πλαίσιο στοίβας. Όταν δημιουργείται ένα νέο πλαίσιο στοίβας επειδή καλείται μια συνάρτηση, ο καταχωρητήςx29
αποθηκεύεται στη στοίβα και η νέα διεύθυνση πλαισίου (διεύθυνσηsp
) αποθηκεύεται σε αυτό τον καταχωρητή.
Αυτός ο καταχωρητής μπορεί επίσης να χρησιμοποιηθεί ως καταχωρητής γενικής χρήσης αν και συνήθως χρησιμοποιείται ως αναφορά σε τοπικές μεταβλητές.
x30
ήlr
- Καταχωρητής Συνδέσμου. Κ
Καταχωρητές Συστήματος
Υπάρχουν εκατοντάδες καταχωρητές συστήματος, επίσης ονομάζονται καταχωρητές ειδικού σκοπού (SPRs), που χρησιμοποιούνται για την παρακολούθηση και έλεγχο της συμπεριφοράς των επεξεργαστών.
Μπορούν να διαβαστούν ή να οριστούν μόνο χρησιμοποιώντας τις αφιερωμένες ειδικές εντολές mrs
και msr
.
Οι ειδικοί καταχωρητές TPIDR_EL0
και TPIDDR_EL0
συναντώνται συχνά κατά την αντιστροφή μηχανικής. Το επίθετο EL0
υποδηλώνει την ελάχιστη εξαίρεση από την οποία ο καταχωρητής μπορεί να προσπελαστεί (σε αυτήν την περίπτωση το EL0 είναι το κανονικό επίπεδο εξαίρεσης (προνόμιο) που τρέχουν τα κανονικά προγράμματα).
Συχνά χρησιμοποιούνται για να αποθηκεύουν την βασική διεύθυνση της περιοχής αποθήκευσης τοπικών νημάτων μνήμης. Συνήθως ο πρώτος είναι αναγνώσιμος και εγγράψιμος για προγράμματα που τρέχουν στο EL0, αλλά ο δεύτερος μπορεί να διαβαστεί από το EL0 και να γραφτεί από το EL1 (όπως το πυρήνας).
mrs x0, TPIDR_EL0 ; Διάβασε το TPIDR_EL0 στο x0
msr TPIDR_EL0, X0 ; Γράψε το x0 στο TPIDR_EL0
PSTATE
Το PSTATE περιέχει αρκετά στοιχεία διεργασίας που έχουν σειριοποιηθεί στον ορατό από το λειτουργικό σύστημα ειδικό καταχωρητή SPSR_ELx
, όπου το X είναι το επίπεδο άδειας της πυροδότησης εξαίρεσης (αυτό επιτρέπει την ανάκτηση της κατάστασης της διεργασίας όταν η εξαίρεση τελειώνει).
Αυτά είναι τα προσβάσιμα πεδία:
Τα σημαία συνθήκης
N
,Z
,C
καιV
:Το
N
σημαίνει ότι η λειτουργία παρήγαγε αρνητικό αποτέλεσμαΤο
Z
σημαίνει ότι η λειτουργία παρήγαγε μηδένΤο
C
σημαίνει ότι η λειτουργία μεταφέρθηκεΤο
V
σημαίνει ότι η λειτουργία παρήγαγε υπερχείλιση με πρόσημο:Το άθροισμα δύο θετικών αριθμών παράγει αρνητικό αποτέλεσμα.
Το άθροισμα δύο αρνητικών αριθμών παράγει θετικό αποτέλεσμα.
Στην αφαίρεση, όταν από ένα μικρότερο θετικό αριθμό αφαιρεθεί ένας μεγαλύτερος αρνητικός αριθμός (ή αντίστροφα), και το αποτέλεσμα δεν μπορεί να αναπαρασταθεί εντός του εύρους του δοθέντος μεγέθους bit.
Φυσικά ο επεξεργαστής δεν γνωρίζει αν η λειτουργία είναι με πρόσημο ή όχι, οπότε θα ελέγξει τα C και V στις λειτουργίες και θα υποδείξει αν υπήρξε μεταφορά στην περίπτωση που ήταν με πρόσημο ή χωρίς.
Όχι όλες οι εντολές ενημερώνουν αυτές τις σημαίες. Κάποιες όπως CMP
ή TST
το κάνουν, και άλλες που έχουν κατάληξη s όπως ADDS
επίσης το κάνουν.
Η τρέχουσα σημαία πλάτους καταχωρητή (
nRW
): Αν η σημαία κρατά την τιμή 0, το πρόγραμμα θα τρέξει στην κατάσταση εκτέλεσης AArch64 μόλις επαναφερθεί.Το τρέχον Επίπεδο Εξαίρεσης (
EL
): Ένα κανονικό πρόγραμμα που τρέχει στο EL0 θα έχει την τιμή 0Η σημαία μονής βήματος (
SS
): Χρησιμοποιείται από debuggers για τη μονοβήματη εκτέλεση καθορίζοντας τη σημαία SS σε 1 μέσα στοSPSR_ELx
μέσω μιας εξαίρεσης. Το πρόγραμμα θα εκτελέσει ένα βήμα και θα εκδώσει μια εξαίρεση μονοβήματος.Η σημαία κατάστασης παράνομης εξαίρεσης (
IL
): Χρησιμοποιείται για να επισημάνει όταν ένα προνομιούχο λογισμικό εκτελεί μια μη έγκυρη μεταφορά επιπέδου εξαίρεσης, αυτή η σημαία ορίζεται σε 1 και ο επεξεργαστής εκδηλώνει μια παράνομη κατάσταση εξαίρεσης.Οι σημαίες
DAIF
: Αυτές οι σημαίες επιτρέπουν σε ένα προνομιούχο πρόγραμμα να μάσκαρει εκλεκτικά ορισμένες εξωτερικές εξαιρέσεις.Αν το
A
είναι 1 σημαίνει ότι θα πυροδοτηθούν ασύγχρονες αποτυχίες. ΤοI
ρυθμίζει την ανταπόκριση σε εξωτερικά υλικά Αιτήματα Διακοπών (IRQs) και το F σχετίζεται με τα Αιτήματα Γρήγορων Διακοπών (FIRs).Οι σημαίες επιλογής δείκτη στοίβας (
SPS
): Τα προνομιούχα προγράμματα που τρέχουν στο EL1 και πάνω μπορούν να αλλάζουν μεταξύ της χρήσης του δικού τους καταχωρητή δείκτη στοίβας και του καταχωρητή δείκτη χρήστη (π.χ. μεταξύSP_EL1
καιEL0
). Αυτή η αλλαγή γίνεται με την εγγραφή στον ειδικό καταχωρητήSPSel
. Αυτό δεν μπορεί να γίνει από το EL0.
Σύμβαση Κλήσης (ARM64v8)
Η σύμβαση κλήσης ARM64 καθορίζει ότι οι πρώτες οκτώ παράμετροι μιας συνάρτησης περνιούνται στους καταχωρητές x0
έως x7
. Επιπλέον παράμετροι περνιούνται στη στοίβα. Η τιμή επιστροφής περνιέται πίσω στον καταχωρητή x0
, ή στον x1
επίσης αν είναι 128 bits μακριά. Οι καταχωρητές x19
έως x30
και sp
πρέπει να διατηρηθούν μεταξύ κλήσεων συναρτήσεων.
Όταν διαβάζετε μια συνάρτηση σε συναρμολόγηση, ψάξτε για το προλόγο και επίλογο της συνάρτησης. Ο πρόλογος συνήθως περιλαμβάνει το αποθήκευση του δείκτη πλαισίου (x29
), την ρύθμιση ενός νέου δείκτη πλαισίου και την κατανομή χώρου στοίβας. Ο επίλογος συνήθως περιλαμβάνει την επαναφορά του αποθηκευμένου δείκτη πλαισίου και την επιστροφή από τη συνάρτηση.
Σύμβαση Κλήσης στη Swift
Η Swift έχει τη δική της σύμβαση κλήσης που μπορεί να βρεθεί στο [https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64](https://github.com/apple/swift/blob/main
Σύνταξη: add(s) Xn1, Xn2, Xn3 | #imm, [shift #N | RRX]
Xn1 -> Προορισμός
Xn2 -> Τελεστής 1
Xn3 | #imm -> Τελεστής 2 (καταχώρηση ή άμεσο)
[shift #N | RRX] -> Εκτέλεση μετατόπισης ή κλήση RRX
Παράδειγμα:
add x0, x1, x2
— Αυτό προσθέτει τις τιμές σταx1
καιx2
μαζί και αποθηκεύει το αποτέλεσμα στοx0
.add x5, x5, #1, lsl #12
— Αυτό ισούται με 4096 (ένα 1 μετατοπισμένο 12 φορές) -> 1 0000 0000 0000 0000adds
Αυτό εκτελεί έναadd
και ενημερώνει τα σημαίαsub
: Αφαίρεση των τιμών δύο καταχωρητών και αποθήκευση του αποτελέσματος σε έναν καταχωρητή.Ελέγξτε τη σύνταξη του
add
.Παράδειγμα:
sub x0, x1, x2
— Αυτό αφαιρεί την τιμή από τοx2
από τοx1
και αποθηκεύει το αποτέλεσμα στοx0
.subs
Αυτό είναι σαν το sub αλλά ενημερώνει τη σημαίαmul
: Πολλαπλασιασμός των τιμών δύο καταχωρητών και αποθήκευση του αποτελέσματος σε έναν καταχωρητή.Παράδειγμα:
mul x0, x1, x2
— Αυτό πολλαπλασιάζει τις τιμές σταx1
καιx2
και αποθηκεύει το αποτέλεσμα στοx0
.div
: Διαίρεση της τιμής ενός καταχωρητή με έναν άλλον και αποθήκευση του αποτελέσματος σε έναν καταχωρητή.Παράδειγμα:
div x0, x1, x2
— Αυτό διαιρεί την τιμή στοx1
με τοx2
και αποθηκεύει το αποτέλεσμα στοx0
.lsl
,lsr
,asr
,ror
,rrx
:Λογική μετατόπιση αριστερά: Προσθήκη 0 από το τέλος μετακινώντας τα υπόλοιπα μπροστά (πολλαπλασιασμός κατά n φορές 2)
Λογική μετατόπιση δεξιά: Προσθήκη 1 στην αρχή μετακινώντας τα υπόλοιπα πίσω (διαίρεση κατά n φορές 2 σε ανυπογραφήτους)
Αριθμητική μετατόπιση δεξιά: Όπως
lsr
, αλλά αντί να προσθέτει 0 αν το πιο σημαντικό ψηφίο είναι 1, προστίθενται 1 (**διαίρεση κατά n φορές 2 σε υπογραφήτους)Περιστροφή δεξιά: Όπως
lsr
αλλά ό,τι αφαιρείται από τα δεξιά προστίθεται στα αριστεράΠεριστροφή Δεξιά με Επέκταση: Όπως
ror
, αλλά με τη σημαία μεταφοράς ως "πιο σημαντικό ψηφίο". Έτσι, η σημαία μεταφοράς μετακινείται στο bit 31 και το αφαιρούμενο bit στη σημαία μεταφοράς.bfm
: Μετακίνηση Πεδίου Μπιτ, αυτές οι λειτουργίες αντιγράφουν τα bits0...n
από μια τιμή και τα τοποθετούν σε θέσειςm..m+n
. Το#s
καθορίζει τη θέση του αριστερότερου bit και το#r
την ποσότητα δεξιάς περιστροφής.Μετακίνηση πεδίου μπιτ:
BFM Xd, Xn, #r
Μετακίνηση πεδίου μπιτ με πρόσημο:
SBFM Xd, Xn, #r, #s
Μετακίνηση πεδίου μπιτ χωρίς πρόσημο:
UBFM Xd, Xn, #r, #s
Εξαγωγή και Εισαγωγή Πεδίου Μπιτ: Αντιγράφει ένα πεδίο μπιτ από έναν καταχωρητή και το αντιγράφει σε έναν άλλον καταχωρητή.
BFI X1, X2, #3, #4
Εισαγωγή 4 bits από το X2 από το 3ο bit του X1BFXIL X1, X2, #3, #4
Εξαγωγή από το 3ο bit του X2 τέσσερα bits και αντιγραφή τους στο X1SBFIZ X1, X2, #3, #4
Επέκταση με πρόσημο 4 bits από το X2 και εισαγωγή τους στο X1 ξεκινώντας από τη θέση bit 3 μηδενίζοντας τα δεξιά bitsSBFX X1, X2, #3, #4
Εξάγει 4 bits ξεκινώντας από το bit 3 από το X2, επεκτείνει το πρόσημο τους και τοποθετεί το αποτέλεσμα στο X1UBFIZ X1, X2, #3, #4
Επέκταση μηδενικών 4 bits από το X2 και εισαγωγή τους στο X1 ξεκινώντας από τη θέση bit 3 μηδενίζοντας τα δεξιά bitsUBFX X1, X2, #3, #4
Εξάγει 4 bits ξεκινώντας από το bit 3 από το X2 και τοποθετεί το αποτέλεσμα με επέκταση μηδενικών στο X1.Επέκταση Προσήμου Σε X: Επεκτείνει το πρόσημο (ή προσθέτει απλά 0 στη μη υπογεγραμμένη έκδοση) μιας τιμής για να είναι δυνατές οι λειτουργίες με αυτή:
SXTB X1, W2
Επεκτείνει το πρόσημο ενός byte από W2 σε X1 (W2
είναι το μισό τουX2
) για να γεμίσει τα 64bitsSXTH X1, W2
Επεκτείνει το πρόσημο ενός 16bit αριθμού από W2 σε X1 για να γεμίσει τα 64bitsSXTW X1, W2
Επεκτείνει το πρόσημο ενός byte από W2 σε X1 για να γεμίσει τα 64bitsUXTB X1, W2
Προσθέτει 0 (μη υπογεγραμμένο) σε ένα byte από W2 σε X1 για να γεμίσει τα 64bitsextr
: Εξάγει bits από ένα συγκεκριμένο ζεύγος καταχωρητών που ενωθήκαν.Παράδειγμα:
EXTR W3, W2, W1, #3
Αυτό θα ενώσει το W1+W2 και θα πάρει από το bit 3 του W2 μέχρι το bit 3 του W1 και θα το αποθηκεύσει στο W3.cmp
: Σύγκριση δύο καταχωρητών και ρύθμιση σημαίων κατάστασης. Είναι ένας ψευδώνυμος τουsubs
με τον προορισμό να είναι ο καταχωρητής μηδέν. Χρήσιμο για να γνωρίζετε ανm == n
.Υποστηρίζει την ίδια σύνταξη με το
subs
Παράδειγμα:
cmp x0, x1
— Αυτό συγκρίνει τις τιμές σταx0
καιx1
και ρυθμίζει τα σημαία κατάστασης αναλόγως.cmn
: Σύγκριση αρνητικού τελεστή. Σε αυτήν την περίπτωση είναι ένας ψευδώνυμο τουadds
και υποστηρίζει την ίδια σύνταξη. Χρήσιμο για να γνωρίζετε ανm == -n
.ccmp
: Συνθήκες σύγκρισης, είναι μια σύγκριση που θα πραγματοποιηθεί μόνο αν μια προηγούμενη σύγκριση ήταν αληθής και θα ρυθμίσει ειδικά τα bits nzcv.cmp x1, x2; ccmp x3, x4, 0, NE; blt _func
-> αν x1 != x2 και x3 < x4, μετάβαση στο funcΑυτό οφείλεται στο γεγονός ότι το
ccmp
θα εκτελεστεί μόνο αν η προηγούμενηcmp
ήτανNE
, αν δεν ήταν, τα bitsnzcv
θα οριστούν σε 0 (που δεν θα ικανοποιήσει τη σύγκρισηblt
).Αυτό μπορεί επίσης να χρησιμοποιηθεί ως `ccmn
b.ne
: Branch if Not Equal. Αυτή η εντολή ελέγχει τα σημαία συνθηκών (τα οποία έχουν οριστεί από μια προηγούμενη εντολή σύγκρισης) και αν οι τιμές που συγκρίθηκαν δεν ήταν ίσες, τότε κάνει άλμα σε ένα ετικέτα ή διεύθυνση.Παράδειγμα: Μετά από μια εντολή
cmp x0, x1
,b.ne label
— Αν οι τιμές σταx0
καιx1
δεν ήταν ίσες, τότε αυτό πηδάει στηνlabel
.cbz
: Σύγκριση και Άλμα σε Μηδέν. Αυτή η εντολή συγκρίνει έναν καταχωρητή με το μηδέν και αν είναι ίσοι, τότε κάνει άλμα σε μια ετικέτα ή διεύθυνση.Παράδειγμα:
cbz x0, label
— Αν η τιμή στοx0
είναι μηδέν, τότε αυτό πηδάει στηνlabel
.cbnz
: Σύγκριση και Άλμα σε Μη Μηδέν. Αυτή η εντολή συγκρίνει έναν καταχωρητή με το μηδέν και αν δεν είναι ίσοι, τότε κάνει άλμα σε μια ετικέτα ή διεύθυνση.Παράδειγμα:
cbnz x0, label
— Αν η τιμή στοx0
δεν είναι μηδέν, τότε αυτό πηδάει στηνlabel
.tbnz
: Δοκιμάζει το bit και πηδάει σε μη μηδένΠαράδειγμα:
tbnz x0, #8, label
tbz
: Δοκιμάζει το bit και πηδάει σε μηδένΠαράδειγμα:
tbz x0, #8, label
Λειτουργίες επιλογής με συνθήκες: Αυτές είναι λειτουργίες οι οποίες η συμπεριφορά τους ποικίλλει ανάλογα με τα συνθηκικά bits.
csel Xd, Xn, Xm, cond
->csel X0, X1, X2, EQ
-> Αν είναι αληθές, X0 = X1, αν είναι ψευδές, X0 = X2csinc Xd, Xn, Xm, cond
-> Αν είναι αληθές, Xd = Xn, αν είναι ψευδές, Xd = Xm + 1cinc Xd, Xn, cond
-> Αν είναι αληθές, Xd = Xn + 1, αν είναι ψευδές, Xd = Xncsinv Xd, Xn, Xm, cond
-> Αν είναι αληθές, Xd = Xn, αν είναι ψευδές, Xd = NOT(Xm)cinv Xd, Xn, cond
-> Αν είναι αληθές, Xd = NOT(Xn), αν είναι ψευδές, Xd = Xncsneg Xd, Xn, Xm, cond
-> Αν είναι αληθές, Xd = Xn, αν είναι ψευδές, Xd = - Xmcneg Xd, Xn, cond
-> Αν είναι αληθές, Xd = - Xn, αν είναι ψευδές, Xd = Xncset Xd, Xn, Xm, cond
-> Αν είναι αληθές, Xd = 1, αν είναι ψευδές, Xd = 0csetm Xd, Xn, Xm, cond
-> Αν είναι αληθές, Xd = <όλα 1>, αν είναι ψευδές, Xd = 0adrp
: Υπολογίζει τη διεύθυνση σελίδας ενός συμβόλου και την αποθηκεύει σε έναν καταχωρητή.Παράδειγμα:
adrp x0, symbol
— Αυτό υπολογίζει τη διεύθυνση σελίδας τουsymbol
και την αποθηκεύει στοx0
.ldrsw
: Φορτώνει μια υπογραμμισμένη 32-μπιτη τιμή από τη μνήμη και επεκτείνει το πρόσημό της σε 64 bits.Παράδειγμα:
ldrsw x0, [x1]
— Αυτό φορτώνει μια υπογραμμισμένη τιμή 32 bits από τη θέση μνήμης στην οποία δείχνει τοx1
, επεκτείνει το πρόσημό της σε 64 bits και την αποθηκεύει στοx0
.stur
: Αποθηκεύει μια τιμή καταχωρητή σε μια θέση μνήμης, χρησιμοποιώντας ένα μετατόπιση από έναν άλλο καταχωρητή.Παράδειγμα:
stur x0, [x1, #4]
— Αυτό αποθηκεύει την τιμή στοx0
στη θέση μνήμης που είναι 4 bytes μεγαλύτερη από τη διεύθυνση που υπάρχει αυτή τη στιγμή στοx1
.svc
: Κάνει μια κλήση συστήματος. Σημαίνει "Supervisor Call". Όταν ο επεξεργαστής εκτελεί αυτή την εντολή, μεταβαίνει από τη λειτουργία χρήστη στη λειτουργία πυρήνα και πηγαίνει σε μια συγκεκριμένη τοποθεσία στη μνήμη όπου βρίσκεται ο κώδικας χειρισμού κλήσης συστήματος του πυρήνα.Παράδειγμα:
Εισαγωγή Συνάρτησης
Αποθήκευση του καταχωρητή συνδέσμου και του δείκτη πλαισίου στη στοίβα:
Ρύθμιση του νέου δείκτη πλαισίου:
mov x29, sp
(ρυθμίζει τον νέο δείκτη πλαισίου για την τρέχουσα συνάρτηση)Διατείνετε χώρο στη στοίβα για τοπικές μεταβλητές (εάν απαιτείται):
sub sp, sp, <size>
(όπου<size>
είναι το πλήθος των bytes που απαιτούνται)
Επίλογος Συνάρτησης
Αποδέσμευση τοπικών μεταβλητών (εάν είχαν διατεθεί):
add sp, sp, <size>
Επαναφορά του μητρώου συνδέσεων και του δείκτη πλαισίου:
Επιστροφή:
ret
(επιστρέφει τον έλεγχο στον καλούντα χρησιμοποιώντας τη διεύθυνση στον register συνδέσμου)
Κατάσταση Εκτέλεσης AARCH32
Το Armv8-A υποστηρίζει την εκτέλεση προγραμμάτων 32-bit. AArch32 μπορεί να τρέξει σε ένα από τα δύο σύνολα εντολών: A32
και T32
και μπορεί να μεταβεί μεταξύ τους μέσω interworking
.
Προνομιούχα προγράμματα 64-bit μπορούν να προγραμματίσουν την εκτέλεση 32-bit προγραμμάτων εκτελώντας μεταφορά επιπέδου εξαίρεσης στο χαμηλότερου επιπέδου προνομιούχο 32-bit.
Σημειώστε ότι η μετάβαση από 64-bit σε 32-bit συμβαίνει με μείωση του επιπέδου εξαίρεσης (για παράδειγμα ένα 64-bit πρόγραμμα σε EL1 προκαλεί ένα πρόγραμμα σε EL0). Αυτό γίνεται με τον ορισμό του bit 4 του ειδικού καταχωρητή SPSR_ELx
σε 1 όταν η διαδικασία νήματος AArch32
είναι έτοιμη για εκτέλεση και το υπόλοιπο του SPSR_ELx
αποθηκεύει τα προγράμματα CPSR του AArch32
. Στη συνέχεια, το προνομιούχο πρόγραμμα καλεί την εντολή ERET
ώστε ο επεξεργαστής να μεταβεί σε AArch32
εισέρχοντας σε A32 ή T32 ανάλογα με το CPSR**.**
Το interworking
συμβαίνει χρησιμοποιώντας τα bits J και T του CPSR. J=0
και T=0
σημαίνει A32
και J=0
και T=1
σημαίνει T32. Αυτό βασικά μεταφράζεται στον ορισμό του χαμηλότερου bit σε 1 για να υποδείξει ότι το σύνολο εντολών είναι T32.
Αυτό ορίζεται κατά τη διάρκεια των εντολών αλλαγής κλάδου interworking, αλλά μπορεί επίσης να οριστεί απευθείας με άλλες εντολές όταν το PC ορίζεται ως καταχωρητής προορισμού. Παράδειγμα:
Άλλο ένα παράδειγμα:
Καταχωρητές
Υπάρχουν 16 καταχωρητές 32-bit (r0-r15). Από τον r0 έως τον r14 μπορούν να χρησιμοποιηθούν για οποιαδήποτε λειτουργία, ωστόσο μερικοί από αυτούς είναι συνήθως διατηρημένοι:
r15
: Δείκτης προγράμματος (πάντα). Περιέχει τη διεύθυνση της επόμενης εντολής. Στο A32 τρέχον + 8, στο T32, τρέχον + 4.r11
: Δείκτης Πλαισίουr12
: Καταχωρητής κλήσης εντός διαδικασίαςr13
: Δείκτης Στοίβαςr14
: Καταχωρητής Συνδέσμου
Επιπλέον, οι καταχωρητές αντιγράφονται σε τράπεζες καταχωρητών
. Αυτά είναι μέρη που αποθηκεύουν τις τιμές των καταχωρητών επιτρέποντας την εκτέλεση γρήγορης αλλαγής πλαισίου στην επεξεργασία εξαιρέσεων και προνομιούχων λειτουργιών για να αποφευχθεί η ανάγκη χειροκίνητης αποθήκευσης και επαναφοράς των καταχωρητών κάθε φορά.
Αυτό γίνεται με το αποθήκευση της κατάστασης του επεξεργαστή από το CPSR
στο SPSR
της λειτουργικής κατάστασης του επεξεργαστή στην οποία γίνεται η εξαίρεση. Κατά την επιστροφή από την εξαίρεση, το CPSR
επαναφέρεται από το SPSR
.
CPSR - Τρέχουσα Κατάσταση Προγράμματος
Στο AArch32 το CPSR λειτουργεί παρόμοια με το PSTATE
στο AArch64 και αποθηκεύεται επίσης στο SPSR_ELx
όταν λαμβάνεται μια εξαίρεση για να αποκατασταθεί αργότερα η εκτέλεση:
Τα πεδία διαιρούνται σε ορισμένες ομάδες:
Κατάσταση Καταχώρησης Προγράμματος (APSR): Αριθμητικές σημαίες και προσβάσιμες από EL0
Καταχωρητές Κατάστασης Εκτέλεσης: Συμπεριφορά διεργασίας (διαχειρίζεται από το λειτουργικό σύστημα).
Κατάσταση Καταχώρησης Προγράμματος (APSR)
Οι σημαίες
N
,Z
,C
,V
(όπως και στο AArch64)Η σημαία
Q
: Τίθεται σε 1 όταν συμβαίνει κορεσμός ακεραιών κατά την εκτέλεση μιας εξειδικευμένης αριθμητικής εντολής κορεσμού. Μόλις τεθεί σε1
, θα διατηρήσει την τιμή μέχρι να τεθεί χειροκίνητα σε 0. Επιπλέον, δεν υπάρχει καμία εντολή που ελέγχει την τιμή της ρητά, πρέπει να γίνει ανάγνωση χειροκίνητα.GE
(Μεγαλύτερο από ή ίσο με) Σημαίες: Χρησιμοποιούνται σε λειτουργίες SIMD (Μοναδική Εντολή, Πολλαπλά Δεδομένα), όπως "παράλληλη πρόσθεση" και "παράλληλη αφαίρεση". Αυτές οι λειτουργίες επιτρέπουν την επεξεργασία πολλαπλών σημείων δεδομένων σε μια μόνο εντολή.
Για παράδειγμα, η εντολή UADD8
προσθέτει τέσσερα ζεύγη bytes (από δύο 32-bit τελεστές) παράλληλα και αποθηκεύει τα αποτελέσματα σε έναν καταχωρητή 32-bit. Στη συνέχεια τίθεται οι GE
σημαίες στο APSR
βάσει αυτών των αποτελεσμάτων. Κάθε σημαία GE αντιστοιχεί σε ένα από τα ζεύγη byte πρόσθεσης, υποδεικνύοντας αν η πρόσθεση για αυτό το ζεύγος byte υπερχείλισε.
Η εντολή SEL
χρησιμοποιεί αυτές τις GE σημαίες για να εκτελέσει συνθήκες.
Καταχωρητές Κατάστασης Εκτέλεσης
Τα bits
J
καιT
: ΤοJ
πρέπει να είναι 0 και αν τοT
είναι 0 χρησιμοποιείται το σύνολο εντολών A32, ενώ αν είναι 1 χρησιμοποιείται το T32.Κατάσταση Ενότητας Μπλοκ IT (
ITSTATE
): Αυτά είναι τα bits από 10-15 και 25-26. Αποθηκεύουν συνθήκες για εντολές μέσα σε μια ομάδα που προηγείται από τοIT
.E
bit: Υποδεικνύει την τελειότητα.Λειτουργία και Μάσκα Εξαιρέσεων Καταχωρητών (0-4): Καθορίζουν την τρέχουσα κατάσταση εκτέλεσης. Το 5ο υποδεικνύει αν το πρόγραμμα τρέχει ως 32bit (ένα 1) ή 64bit (ένα 0). Τα άλλα 4 αντιπροσωπεύουν τη λειτουργία εξαίρεσης που χρησιμοποιείται επί του παρόντος (όταν συμβαίνει μια εξαίρεση και χειρίζεται). Ο αριθμός ορίζει την τρέχουσα προτεραιότητα σε περίπτωση που προκληθεί μια άλλη εξαίρεση ενώ αυτή χειρίζεται.
AIF
: Ορισμένες εξαιρέσεις μπορούν να απενεργοποιηθούν χρησιμοποιώντας τα bitsA
,I
,F
. Αν τοA
είναι 1 σημαίνει ότι θα προκληθούν ασύγχρονες αποτυχίες. ΤοI
ρυθμίζει την ανταπόκριση σε εξωτερικά υλικά Αιτήσεις Διακοπών (IRQs). και το F σχετίζεται με τις Γρήγορες Αιτήσεις Διακοπών (FIRs).
Μερικές φορές είναι πιο εύκολο να ελέγξετε τον αποκωδικοποιημένο κώδικα από το libsystem_kernel.dylib
από τον έλεγχο του πηγαίου κώδικα επειδή ο κώδικας αρκετών συστοιχιών (BSD και Mach) δημιουργείται μέσω scripts (ελέγξτε τα σχόλια στον πηγαίο κώδικα), ενώ στο dylib μπορείτε να βρείτε τι καλείται.
κλήσεις machdep
Το XNU υποστηρίζει έναν άλλο τύπο κλήσεων που ονομάζονται εξαρτημένες από τη μηχανή. Ο αριθμός αυτών των κλήσεων εξαρτάται από την αρχιτεκτονική και ούτε οι κλήσεις ούτε οι αριθμοί είναι εγγυημένο ότι θα παραμείνουν σταθεροί.
σελίδα comm
Αυτή είναι μια σελίδα μνήμης ιδιοκτήτη του πυρήνα που αντιστοιχίζεται στον χώρο διεύθυνσης κάθε διεργασίας χρήστη. Έχει σκοπό να κάνει τη μετάβαση από τη λειτουργία χρήστη στον πυρήνα πιο γρήγορη από τη χρήση κλήσεων συστήματος για υπηρεσίες πυρήνα που χρησιμοποιούνται τόσο πολύ ώστε αυτή η μετάβαση θα ήταν πολύ αναποτελεσματική.
Για παράδειγμα, η κλήση gettimeofdate
διαβάζει την τιμή του timeval
απευθείας από τη σελίδα comm.
objc_msgSend
Είναι πολύ συνηθισμένο να βρείτε αυτήν τη συνάρτηση που χρησιμοποιείται σε προγράμματα Objective-C ή Swift. Αυτή η συνάρτηση επιτρέπει την κλήση μιας μεθόδου ενός αντικειμένου Objective-C.
Παράμετροι (περισσότερες πληροφορίες στα έγγραφα):
x0: self -> Δείκτης προς την περίπτωση
x1: op -> Επιλογέας της μεθόδου
x2... -> Υπόλοιπα ορίσματα της κληθείσας μεθόδου
Έτσι, αν τοποθετήσετε ένα σημείο ανακοπής πριν από το κλάδο αυτής της συνάρτησης, μπορείτε εύκολα να βρείτε τι καλείται στο lldb με (σε αυτό το παράδειγμα το αντικείμενο καλεί ένα αντικείμενο από NSConcreteTask
που θα εκτελέσει μια εντολή):
Shellcodes
Για να μεταγλωτίσετε:
Για να εξάγετε τα bytes:
Για νεότερα macOS:
Last updated