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-बिट (8-बाइट) मान स्टोर कर सकता है। 32-बिट मानों की आवश्यकता वाले ऑपरेशनों के लिए, एक ही रजिस्टरों को 32-बिट मोड में एक्सेस किया जा सकता है जिनके नाम w0 से w30 हैं।
x0
सेx7
- इन्हें सामान्यत: स्क्रैच रजिस्टर्स के रूप में और सबरूटीन्स को पैरामीटर पास करने के लिए उपयोग किया जाता है।
x0
एक फ़ंक्शन के रिटर्न डेटा को भी लेता है
x8
- लिनक्स कर्नेल में,x8
svc
इंस्ट्रक्शन के लिए सिस्टम कॉल नंबर के रूप में उपयोग किया जाता है। macOS में x16 का उपयोग होता है!x9
सेx15
- अधिक सामान्य रजिस्टर, अक्सर स्थानीय चरों के लिए उपयोग किए जाते हैं।x16
औरx17
- अंतर-प्रक्रियात्मक कॉल रजिस्टर। तत्काल मूल्यों के लिए अस्थायी रजिस्टर। ये अंधकारित फ़ंक्शन कॉल्स और PLT (Procedure Linkage Table) स्टब्स के लिए भी उपयोग किए जाते हैं।
x16
macOS मेंsvc
इंस्ट्रक्शन के लिए सिस्टम कॉल नंबर के रूप में उपयोग किया जाता है।
x18
- प्लेटफ़ॉर्म रजिस्टर। यह एक सामान्य उद्देश्य रजिस्टर के रूप में उपयोग किया जा सकता है, लेकिन कुछ प्लेटफ़ॉर्मों पर, यह रजिस्टर प्लेटफ़ॉर्म-विशेष उपयोगों के लिए सुरक्षित ओएस में मौजूदा कार्य संरचना के लिए आरक्षित है: विंडोज में वर्तमान धागे पर्यावरण ब्लॉक के लिए पॉइंटर, या लिनक्स कर्नेल में वर्तमान निष्पादित कार्य संरचना के लिए पॉइंटर के लिए।x19
सेx28
- ये कॉली-सेव्ड रजिस्टर हैं। एक फ़ंक्शन को इन रजिस्टरों के मानों को अपने कॉलर के लिए संरक्षित रखना चाहिए, इसलिए वे स्टैक में स्टोर किए जाते हैं और कॉलर के पास जाने से पहले पुनः प्राप्त किए जाते हैं।x29
- फ्रेम पॉइंटर स्टैक फ्रेम का ट्रैक रखने के लिए। जब एक नया स्टैक फ्रेम बनाया जाता है क्योंकि एक फ़ंक्शन को कॉल किया जाता है, तोx29
रजिस्टर को स्टैक में स्टोर किया जाता है और नया फ्रेम पॉइंटर पता (sp
पता) इस रजिस्ट्री में स्टोर किया जाता है।
यह रजिस्टर एक सामान्य उद्देश्य रजिस्टर के रूप में भी उपयोग किया जा सकता है हालांकि यह आम तौर पर स्थानीय चरों के संदर्भ के रूप में उपयोग किया जाता है।
x30
या **
सिस्टम रजिस्टर
सैकड़ों सिस्टम रजिस्टर होते हैं, जिन्हें विशेष उद्देश्य रजिस्टर (SPRs) भी कहा जाता है, जो प्रोसेसर के व्यवहार को निगरानी और नियंत्रण के लिए उपयोग किया जाता है।
इन्हें केवल विशेष निर्दिष्ट निर्देश का उपयोग करके पढ़ा या सेट किया जा सकता है mrs
और msr
।
विशेष रजिस्टर TPIDR_EL0
और TPIDDR_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
का अर्थ है कि ऑपरेशन एक साइन ओवरफ्लो दिया:दो सकारात्मक संख्याओं का योगदान एक नकारात्मक परिणाम देता है।
दो नकारात्मक संख्याओं का योगदान एक सकारात्मक परिणाम देता है।
घटना घटना, जब एक बड़ी नकारात्मक संख्या से एक छोटी सकारात्मक संख्या को घटाया जाता है (या उल्टा), और परिणाम दिए गए बिट आकार की सीमा के भीतर प्रतिनिधित नहीं किया जा सकता है।
स्वाभाविक रूप से प्रोसेसर को यह नहीं पता कि ऑपरेशन साइन है या नहीं, इसलिए यह C और V की जांच करेगा ऑपरेशन में और यह सूचित करेगा कि यदि एक कैरी हुई थी यदि यह साइन था या असाइन।
सभी निर्देश इन ध्वजों को अपडेट नहीं करते। कुछ जैसे CMP
या TST
करते हैं, और अन्य जिनका s सफ़िक्स है जैसे ADDS
भी ऐसा करते हैं।
वर्तमान रजिस्टर चौड़ाई (
nRW
) ध्वज: यदि ध्वज मान 0 में है, तो कार्यक्रम AArch64 निष्पादन स्थिति में चलेगा जब फिर से आरंभ होगा।वर्तमान अपवाद स्तर (
EL
): EL0 में चल रहे एक नियमित कार्यक्रम का मान 0 होगाएकल कदम चलाने का ध्वज (
SS
): डीबगर्स द्वारा एकल कदम चलाने के लिए उपयोग किया जाता है जब एक अपवाद के माध्यम सेSPSR_ELx
में SS ध्वज को 1 सेट करके। कार्यक्रम एक कदम चलाएगा और एक एकल कदम अपवाद जारी करेगा।अवैध अपवाद स्थिति ध्वज (
IL
): यह चिह्नित करने के लिए उपयोग किया जाता है जब एक विशेषाधिकार सॉफ़्टवेयर एक अवैध अपवाद स्तर स्थानांतरण करता है, यह ध्वज 1 में सेट किया जाता है और प्रोसेसर एक अवैध स्थिति अपवाद ट्रिगर करता है।DAIF
ध्वज: ये ध्वज एक विशेषाधिकार कार्यक्रम को विविध बाह्य अपवादों को वैकल्पिक रूप से मास्क करने की अनुमति देते हैं।यदि
A
1 है तो यह अर्धसंगत अबॉर्ट्स को ट्रिगर करेगा।I
बाह्य हार्डवेयर इंटरप्ट अनुरोधों (IRQs) का प्रतिक्रिया करने के लिए कॉन्फ़िगर करता है। और F फास्ट इंटरप्ट अनुरोधों (FIRs) से संबंधित है।स्टैक प्वाइंटर सेलेक्ट ध्वज (
SPS
): EL1 और इसके ऊपर चल रहे विशेषाधिकार कार्यक्रम अपने स्वयं के स्टैक प्वाइंटर रजिस्टर और उपयोगकर्ता मॉडल वाले के बीच ट्रांसफर कर सकते हैं (जैसेSP_EL1
औरEL0
के बीच)। यह परिवर्तन EL0 से नहीं किया जा सकता।
कॉलिंग कनवेंशन (ARM64v8)
ARM64 कॉलिंग कनवेंशन निर्दिष्ट करता है कि पहले आठ पैरामीटर एक फ़ंक्शन में रजिस्टर्स x0
से x7
के माध्यम से पारित किए जाते हैं। अतिरिक्त पैरामीटर स्टैक पर पारित किए जाते हैं। वापसी मान रजिस्टर x0
में वापस पारित किया जाता है, या यदि यह 128 बिट लंबा है तो x1
में भी। x19
से x30
और sp
रजिस्टर को फ़ंक्शन कॉल के बीच सुरक्षित रखना चाहिए।
एक फ़ंक्शन को असेंबली में पढ़ते समय, फ़ंक्शन प्रोलॉग और एपिलॉग के लिए देखें। प्रोलॉग आमतौर पर फ्रेम पॉइंटर को सहेजना (x29
), नया फ्रेम पॉइंटर सेट करना, और स्टैक स्थान आवंटित करना शामिल होता है। एपिलॉग आमतौर पर सहेजे गए फ्रेम पॉइंटर को पुनर्स्थापित करना और फ़ंक्शन से वापस लौटना शामिल होता है।
स्विफ्ट में कॉलिंग कनवेंशन
स्विफ्ट का अपना कॉलिंग कनवेंशन होता है जो https://github.com/apple/swift/blob/main/docs/ABI/CallConvSummary.rst#arm64 में पाया जा सकता है।
सामान्य निर्देश (ARM64v8)
ARM64 निर्देशों का सामान्य रूप से स्वरूप ऑपकोड dst, src1, src2
होता है, जहां ऑपकोड
वह ऑपरेशन होता है जो किया जाना है (जैसे जोड़ें
, घटाएं
, मूव
, आ
वाक्याकार: 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
— यहx1
सेx2
की मानों को घटाता है और परिणाम कोx0
में संग्रहित करता है।subs
यह सब की तरह है लेकिन ध्वज को अपडेट करता है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
की तरह, लेकिन यदि सबसे महत्वपूर्ण बिट 1 है, **1s जोड़े जाते हैं (**अंकगणित में n बार 2 से विभाजित)दाएं घुमाएं:
lsr
की तरह, लेकिन जो कुछ भी दाएं से हटाया जाता है, वह बाएं में जोड़ा जाता हैविस्तार के साथ दाएं घुमाएं:
ror
की तरह, लेकिन कैरी ध्वज को "सबसे महत्वपूर्ण बिट" के रूप में ले जाया जाता है। इसलिए कैरी ध्वज को बिट 31 और हटाए गए बिट को कैरी ध्वज में स्थानांतरित किया जाता है।bfm
: बिट फाइल्ड मूव, ये ऑपरेशन एक मान से बिट0...n
की प्रतिलिपि बनाते हैं और उन्हें स्थानोंm..m+n
में रखते हैं।#s
बाएं सबसे अधिक बिट स्थिति और#r
दाएं घुमाने की मात्रा को निर्दिष्ट करता है।बिटफाइल्ड मूव:
BFM Xd, Xn, #r
साइन बिटफील्ड मूव:
SBFM Xd, Xn, #r, #s
असाइन्ड बिटफील्ड मूव:
UBFM Xd, Xn, #r, #s
बिटफील्ड निकालना और डालना: एक रजिस्टर से एक बिटफील्ड की प्रतिलिपि बनाएं और उसे दूसरे रजिस्टर में कॉपी करें।
BFI X1, X2, #3, #4
X2 से 3 वें बिट से 4 बिट डालें X1 मेंBFXIL X1, X2, #3, #4
3 वें बिट से X2 से चार बिट निकालें और उन्हें X1 में कॉपी करेंSBFIZ X1, X2, #3, #4
X2 से 4 बिट का साइन विस्तार करें और उन्हें X1 में डालें जो बिट स्थिति 3 से शुरू होती है और दाएं बिट्स को शून्य करते हैंSBFX X1, X2, #3, #4
X2 से 3 वें बिट से 4 बिट निकालें, साइन विस्तार करें, और परिणाम को X1 में रखेंUBFIZ X1, X2, #3, #4
X2 से 4 बिट का शून्य विस्तार करें और उन्हें X1 में डालें जो बिट स्थिति 3 से शुरू होती है और दाएं बिट्स को शून्य करते हैंUBFX X1, X2, #3, #4
X2 से 3 वें बिट से 4 बिट निकालें और उन्हें X1 में शून्य विस्तारित परिणाम में रखें।चिह्न विस्तार करें तक X: एक मान का साइन विस्तार करता है (या केवल 0s जोड़ता है असाइन्ड संस्करण में) उसके साथ कार्रवाई करने के लिए:
SXTB X1, W2
W2 से X1 तक एक बाइट के साइन को विस्तारित करता है (W2
X2
का आधा है) 64 बिट भरने के लिएSXTH X1, W2
W2 से X1 तक 16 बिट नंबर का साइन विस्तार करता है 64 बिट भरने के लिएSXTW X1, W2
W2 से X1 तक एक बाइट के साइन को विस्तारित करता है 64 बिट भरने के लिएUXTB X1, W2
एक बाइट को 0s जोड़ता है (असाइन्ड) W2 से X1 तक 64 बिट भरने के लिएextr
: एक निर्दिष्ट जोड़े गए रजिस्टरों से बिट निकालता है।उदाहरण:
EXTR W3, W2, W1, #3
यह W1+W2 को W2 के 3 वें बिट से W1 के 3 वें बिट तक लेता है और इसे W3 में संग्रहित करता है।cmp
: दो रजिस्टरों की तुलना करें और स्थिति ध्वज सेट करें। यह एकsubs
का उपनाम है जो गंतव्य रजिस्टर को शून्य रजिस्टर पर सेट करता है।m == n
के बारे में जानने के लिए उपयुक्त है।यह
subs
के समान सिंटेक्स का समर्थन करता हैउदाहरण:
cmp x0, x1
— यहx0
औरx1
में मानों की तुलना करता है और अनुसार स्थिति ध्वज सेट करता है।cmn
: असंतुलन ऑपरेंड। इस मामले में यह एकadds
का उपनाम है और एक ही सिंटेक्स का समर्थन करता है।m == -n
के बारे में जानने के लिए उपयुक्त है।ccmp
: शर्तमय तुलना, यह एक तुलना है जो केवल यदि पिछली तुलना सत्य थी और विशेष रूप से nzcv बिट सेट करेगी।cmp x1, x2; ccmp x3, x4, 0, NE; blt _func
-> यदि x1 != x2 और x3 < x4, _func पर जाएंयह इसलिए है क्योंकि
ccmp
केवल उस समय निष्पादित किया जाएगा जब पिछलीcmp
एकNE
था, अगर यह नहीं था तो बिटnzcv
को 0 पर सेट किया जाएगा (जोblt
तुलना को संतुष्ट नहीं करेगा)।इसे
ccmn
के रूप में भी उपयोग किया जा सकता है (वही लेकिन नकारात्मक, जैसेcmp
vscmn
।)tst
: यह जांचता है कि तुलb.ne
: ब्रांच अगर बराबर नहीं। यह निर्धारित ध्वज (जो पिछले तुलना निर्देश द्वारा सेट किए गए थे) की स्थिति की जांच करता है, और यदि तुलना की गई मान समान नहीं थे, तो यह एक लेबल या पते पर ब्रांच करता है।उदाहरण:
cmp x0, x1
निर्देश के बाद,b.ne label
— यदिx0
औरx1
में मान समान नहीं थे, तो यहlabel
पर जाता है।cbz
: जीरो पर तुलना और ब्रांच। यह निर्देश एक रजिस्टर को शून्य के साथ तुलना करता है, और यदि वे समान हैं, तो यह एक लेबल या पते पर ब्रांच करता है।उदाहरण:
cbz x0, label
— यदिx0
में मान शून्य है, तो यहlabel
पर जाता है।cbnz
: जीरो पर तुलना और ब्रांच नॉन-जीरो। यह निर्देश एक रजिस्टर को शून्य के साथ तुलना करता है, और यदि वे समान नहीं हैं, तो यह एक लेबल या पते पर ब्रांच करता है।उदाहरण:
cbnz x0, label
— यदिx0
में मान गैर-शून्य है, तो यहlabel
पर जाता है।tbnz
: टेस्ट बिट और ब्रांच ऑन नॉनजीरोउदाहरण:
tbnz x0, #8, label
tbz
: टेस्ट बिट और ब्रांच ऑन जीरोउदाहरण:
tbz x0, #8, label
शर्ताधीन चयन कार्याएँ: ये कार्याएँ वे हैं जिनका व्यवहार शर्ताधीन बिट्स पर निर्भर करता है।
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 = <all 1>, अगर झूठ, Xd = 0adrp
: एक प्रतीक का पृष्ठ पता गणना करें और इसे एक रजिस्टर में संग्रहीत करें।उदाहरण:
adrp x0, symbol
— यहsymbol
का पृष्ठ पता गणना करता है औरx0
में संग्रहीत करता है।ldrsw
: मेमोरी से एक साइन एक्सटेंडेड 64 बिट तक का साइन्ड 32-बिट मान लोड करें।उदाहरण:
ldrsw x0, [x1]
— यहx1
द्वारा संकेतित मेमोरी स्थान से एक साइन्ड 32-बिट मान लोड करता है, इसे 64 बिट तक साइनएक्सटेंड करता है, और इसेx0
में संग्रहीत करता है।stur
: एक रजिस्टर मान को मेमोरी स्थान पर स्टोर करें, एक अन्य रजिस्टर से एक ऑफसेट का उपयोग करके।उदाहरण:
stur x0, [x1, #4]
— यहx1
में वर्तमान मेमोरी पते से 4 बाइट अधिक होने वाले पते में मान को स्टोर करता है।svc
: सिस्टम कॉल करें। यह "सुपरवाइजर कॉल" के लिए खड़ा है। जब प्रोसेसर इस निर्देश को निष्पादित करता है, तो यह उपयोगकर्ता मोड से कर्णेल मोड में स्विच करता है और मेमोरी में एक विशिष्ट स्थान पर जाता है जहां कर्णेल की सिस्टम कॉल हैंडलिंग कोड स्थित है।उदाहरण:
कार्य का प्रोलॉग
लिंक रजिस्टर और फ्रेम प्वाइंटर को स्टैक में सहेजें:
नए फ्रेम पॉइंटर सेट करें:
mov x29, sp
(वर्तमान फ़ंक्शन के लिए नए फ्रेम पॉइंटर सेट करता है)स्थानीय चर के लिए स्टैक पर स्थान आवंटित करें (यदि आवश्यक हो):
sub sp, sp, <size>
(जहां<size>
आवश्यक बाइट्स की संख्या है)
फ़ंक्शन एपिलॉग
स्थानीय चरों को डीएलीक्वेट करें (यदि कोई आवंटित किए गए हो):
add sp, sp, <size>
लिंक रजिस्टर और फ्रेम पॉइंटर को पुनर्स्थापित करें:
वापसी:
ret
(लिंक रजिस्टर में पते का उपयोग करके कॉलर को नियंत्रण वापस करता है)
AARCH32 निष्पादन स्थिति
Armv8-A 32-बिट कार्यक्रमों का निष्पादन समर्थन करता है। AArch32 एक दो निर्देश सेट में चल सकता है: A32
और T32
और इंटरवर्किंग
के माध्यम से उनमें स्विच कर सकता है।
विशेषाधिकारी 64-बिट कार्यक्रम 32-बिट के निम्न विशेषाधिकारी में एक अपवाद स्तर स्थानांतरण का अनुसूचित कर सकते हैं।
ध्यान दें कि 64-बिट से 32-बिट पराधीनता स्तर कम करने के साथ होता है (उदाहरण के लिए, EL1 में एक 64-बिट कार्यक्रम एल0 में एक कार्यक्रम को ट्रिगर कर रहा है)। यह किया जाता है SPSR_ELx
विशेष रजिस्टर के बिट 4 को 1 सेट करके जब AArch32
प्रक्रिया धागा निष्पादित होने के लिए तैयार होता है और बाकी SPSR_ELx
में AArch32
कार्यक्रम CPSR को संग्रहित करता है। फिर, विशेषाधिकारी प्रक्रिया ERET
निर्देश को कॉल करती है ताकि प्रोसेसर AArch32
में परिवर्तित हो जाए जो CPSR के आधार पर A32 या T32 में प्रवेश करता है**.**
इंटरवर्किंग
J और T बिट्स का उपयोग करके होता है। J=0
और T=0
का मतलब है A32
और J=0
और T=1
का मतलब है T32। यह मूल रूप से इसे दर्शाता है कि निर्देश सेट T32 है।
यह इंटरवर्किंग शाखा निर्देशों के दौरान सेट किया जाता है, लेकिन PC को गंतव्य रजिस्टर के रूप में सेट किया जा सकता है। उदाहरण:
एक और उदाहरण:
रजिस्टर
16 32-बिट रजिस्टर हैं (r0-r15). r0 से r14 वे किसी भी ऑपरेशन के लिए उपयोग किए जा सकते हैं, हालांकि कुछ उनमें से सामान्यत: आरक्षित होते हैं:
r15
: कार्यक्रम काउंटर (हमेशा). अगले निर्देश का पता रखता है। A32 में current + 8, T32 में, current + 4।r11
: फ्रेम पॉइंटरr12
: इंट्रा-प्रोसेडरियल कॉल रजिस्टरr13
: स्टैक पॉइंटरr14
: लिंक रजिस्टर
इसके अतिरिक्त, रजिस्टर बैंक्ड रजिस्ट्रीज
में बैकअप किए जाते हैं। ये जगह हैं जो रजिस्टर मानों को संग्रहीत करती हैं जो अपशिष्ट हैं, अपशिष्ट संभालन और विशेषाधिकारीय कार्यों में त्वरित संदर्भ परिवर्तन करने की अनुमति देती हैं ताकि हर बार रजिस्टर सहेजने और पुनर्स्थापित करने की आवश्यकता न हो।
यह CPSR
से प्रोसेसर मोड के SPSR
में प्रोसेसर स्थिति को सहेजने के द्वारा किया जाता है जिसे अपशिष्ट लिया जाता है। अपशिष्ट वापसी पर, CPSR
को SPSR
से पुनर्स्थापित किया जाता है।
CPSR - वर्तमान कार्यक्रम स्थिति रजिस्टर
AArch32 में CPSR AArch64 में PSTATE
के रूप में काम करता है और एक अपशिष्ट लिया जाता है तो बाद में निष्पादन को पुनर्स्थापित करने के लिए SPSR_ELx
में भी संग्रहीत होता है:
क्षेत्रों को कुछ समूहों में विभाजित किया गया है:
एप्लिकेशन प्रोग्राम स्थिति रजिस्टर (APSR): अंकगणित ध्वज और EL0 से पहुंचने योग्य।
निष्पादन स्थिति रजिस्टर: प्रक्रिया व्यवहार (ओएस द्वारा प्रबंधित)।
एप्लिकेशन प्रोग्राम स्थिति रजिस्टर (APSR)
N
,Z
,C
,V
ध्वज (जैसे AArch64 में)Q
ध्वज: यह 1 पर सेट होता है जब कई विशेषित सीमांकित अंकगणित निर्देश के निष्पादन के दौरान इंटीजर सैट्यूरेशन होता है। एक बार यह1
पर सेट हो जाता है, तो यह वह मान बनाए रखेगा जब तक यह मैन्युअल रूप से 0 पर सेट न हो जाए। इसके अतिरिक्त, इसके मान की जांच करने वाला कोई निर्देश नहीं है, इसे मैन्युअल रूप से पढ़कर किया जाना चाहिए।GE
(अधिक या बराबर) ध्वज: इसका उपयोग SIMD (Single Instruction, Multiple Data) ऑपरेशन में किया जाता है, जैसे "पैरलल जोड़" और "पैरलल कम"। ये ऑपरेशन एक ही निर्देश में कई डेटा बिंदुओं को प्रसंस्करण करने की अनुमति देते हैं।
उदाहरण के लिए, UADD8
निर्देशन चार जोड़ों को जोड़ता है (दो 32-बिट ऑपरेंड से) पैरलल और परिणामों को एक 32-बिट रजिस्टर में संग्रहीत करता है। फिर यह इन परिणामों के आधार पर APSR
में GE
ध्वज सेट करता है। प्रत्येक GE ध्वज एक बाइट जोड़ने के लिए एक का संबंधित है, इसका सूचना देता है कि उस बाइट जोड़ने के लिए अतिरिक्त हो गया है।
SEL
निर्देशन इन GE ध्वजों का उपयोग शर्तानुसार क्रियाएँ करने के लिए करता है।
निष्पादन स्थिति रजिस्टर
J
औरT
बिट:J
0 होना चाहिए और यदिT
0 है तो निर्देश सेट A32 का उपयोग किया जाता है, और यदि यह 1 है, तो T32 का उपयोग किया जाता है।IT ब्लॉक स्थिति रजिस्टर (
ITSTATE
): ये 10-15 और 25-26 से बिट हैं। ये एकIT
प्रिफिक्स ग्रुप के भीतर निर्देशों के लिए स्थितियाँ संग्रहीत करते हैं।E
बिट: एंडियनेस को दर्शाता है।मोड और अपशिष्ट मास्क बिट्स (0-4): वर्तमान निष्पादन स्थिति निर्धारित करते हैं। पांचवां वाला यह दिखाता है कि क्या कार्यक्रम 32-बिट (1) या 64-बिट (0) के रूप में चल रहा है। अन्य 4 वर्तमान में उपयोग किए जा रहे अपशिष्ट मोड को दर्शाते हैं (जब एक अपशिष्ट होता है और इसे संभाला जा रहा है)। संख्या सेट वर्तमान प्राथमिकता को दर्शाती है जिसका अर्थ है कि यदि इसे संभालते समय एक और अपशिष्ट ट्रिगर होता है।
AIF
: कुछ अपशिष्ट को बंद किया जा सकता है उपयोग करके बिट्सA
,I
,F
। यदिA
1 है तो इसका अर्थ है कि असमकालिक अबॉर्ट्स ट्रिगर होंगे।I
बाह्य हार्डवेयर इंटरप्ट रिक्वेस्ट्स (IRQs) का प्रतिक्रिया देने के लिए कॉन्फ़िगर करता है। और F फास्ट इंटरप्ट रिक्वेस्ट्स (FIRs) से संबंधित है।
macOS
BSD सिसकॉल्स
syscalls.master की जाँच करें। BSD सिसकॉल्स में x16 > 0 होगा।
Mach ट्रैप्स
syscall_sw.c में mach_trap_table
और mach_traps.h में प्रोटोटाइप्स की जाँच करें। Mach ट्रैप्स में x16 < 0 होगा, इसलिए आपको पिछली सूची से नंबर को एक माइनस के साथ कॉल करने की आवश्यकता है: _kernelrpc_mach_vm_allocate_trap
-10
है।
आप इन्हें (और BSD) सिसकॉल्स कैसे कॉल करने के लिए खोजने के लिए एक disassembler में libsystem_kernel.dylib
की जाँच कर सकते हैं:
कभी-कभी libsystem_kernel.dylib
से डिकंपाइल कोड की जाँच करना स्रोत कोड की जाँच से आसान होता है क्योंकि कई सिसकॉल्स (बीएसडी और मैक) का कोड स्क्रिप्ट्स के माध्यम से उत्पन्न किया जाता है (स्रोत कोड में टिप्पणियों की जाँच करें) जबकि dylib में आपको यह मिल सकता है कि क्या कॉल किया जा रहा है।
machdep कॉल
XNU एक और प्रकार के कॉल का समर्थन करता है जिसे मशीन निर्भर कहा जाता है। इन कॉल की संख्या वास्तविकता और न कॉल और न ही संख्याएँ स्थिर रहने की गारंटी है।
comm पेज
यह एक कर्नेल मालिक मेमोरी पेज है जो हर उपयोगकर्ता प्रक्रिया के पते में मैप किया जाता है। यह उपयोगकर्ता मोड से कर्नेल स्पेस में जाने की तुलना में कर्नेल सेवाओं के लिए सिसकॉल का उपयोग करना ज्यादा असरदार है।
उदाहरण के लिए कॉल gettimeofdate
timeval
के मान को सीधे comm पेज से पढ़ता है।
objc_msgSend
यह फ़ंक्शन Objective-C या Swift कार्यक्रमों में उपयोग किया जाने वाला बहुत ही सामान्य है। यह फ़ंक्शन एक Objective-C ऑब्जेक्ट का एक मेथड कॉल करने की अनुमति देता है।
पैरामीटर (अधिक जानकारी दस्तावेज़ में):
x0: self -> इंस्टेंस के पॉइंटर
x1: op -> मेथड का सेलेक्टर
x2... -> आमंत्रित मेथड के शेष तर्क
इसलिए, यदि आप इस फ़ंक्शन के शाखा के पहले ब्रेकपॉइंट डालते हैं, तो आप आसानी से lldb में जांच सकते हैं कि इसमें क्या आमंत्रित है (इस उदाहरण में ऑब्जेक्ट NSConcreteTask
से ऑब्जेक्ट कॉल करता है जो एक कमांड चलाएगा):
चरित्र NSObjCMessageLoggingEnabled=1
को सेट करने से इस फ़ंक्शन को जब कॉल किया जाता है तो /tmp/msgSends-pid
जैसी फ़ाइल में लॉग करना संभव है।
इसके अतिरिक्त, OBJC_HELP=1
को सेट करके और किसी भी बाइनरी को कॉल करके आप देख सकते हैं कि आप किस प्रकार के अन्य पर्यावरण चर उपयोग कर सकते हैं जब कुछ निश्चित Objc-C क्रियाएँ होती हैं।
जब यह फ़ंक्शन कॉल होता है, तो इस निर्दिष्ट उदाहरण के तत्व का पता लगाना आवश्यक होता है, इसके लिए विभिन्न खोज की जाती हैं:
आशावादी कैश लुकअप करें:
यदि सफल हो, तो समाप्त
रनटाइमलॉक प्राप्त करें (पढ़ें)
यदि (रियलाइज़ और !cls->realized) तो कक्षा को रियलाइज़ करें
यदि (आरंभ करें और !cls->initialized) तो कक्षा को प्रारंभ करें
कक्षा का खुद का कैश प्रयास करें:
यदि सफल हो, तो समाप्त
कक्षा का विधि सूची प्रयास करें:
यदि पाया गया, तो कैश भरें और समाप्त
उपकक्ष कैश प्रयास करें:
यदि सफल हो, तो समाप्त
उपकक्ष विधि सूची प्रयास करें:
यदि पाया गया, तो कैश भरें और समाप्त
यदि (रिज़ॉल्वर) विधि रिज़ॉल्वर का प्रयास करें, और कक्षा लुकअप से दोहराएं
अगर फिर भी यहाँ हैं (= सभी अन्य विफल हो गए हैं) तो फॉरवर्डर का प्रयास करें
शैलकोड
कॉम्पाइल करने के लिए:
बाइट्स को निकालने के लिए: