इनलाइन असेंबलर
कंप्यूटर प्रोग्रामिंग में, एक इनलाइन असेंबलर कुछ संकलक्स की एक विशेषता है जो असेंबली भाषा में लिखे गए निम्न-स्तरीय कोड को प्रोग्राम के भीतर एम्बेड करने की अनुमति देता है, कोड के बीच जो अन्यथा उच्च-स्तरीय भाषा से संकलित किया गया है। उच्च-स्तरीय भाषा जैसे कि C (प्रोग्रामिंग लैंग्वेज) या Ada प्रोग्रामिंग लैंग्वेज।
प्रेरणा और विकल्प
असेंबली लैंग्वेज कोड की एम्बेडिंग आमतौर पर इनमें से किसी एक कारण से की जाती है:[1]
- अनुकूलन (कंप्यूटर विज्ञान): प्रोग्रामर अपने प्रोग्राम के कलन विधि के सबसे अधिक प्रदर्शन-संवेदनशील भागों को लागू करने के लिए असेंबली भाषा कोड का उपयोग कर सकते हैं, कोड जो संकलक द्वारा अन्यथा उत्पन्न होने की तुलना में अधिक कुशल होने के लिए उपयुक्त है।
- प्रोसेसर विशिष्ट निर्देश (कंप्यूटर विज्ञान) तक पहुंच: अधिकांश प्रोसेसर विशेष निर्देश प्रदान करते हैं, जैसे तुलना-और-स्वैप और परीक्षण-और-सेट निर्देश जिनका उपयोग सेमाफोर (प्रोग्रामिंग) या अन्य सिंक्रनाइज़ेशन और लॉकिंग आदिम बनाने के लिए किया जा सकता है। लगभग हर आधुनिक प्रोसेसर में ये या एमएमएक्स (निर्देश सेट) हैं, क्योंकि वे कंप्यूटर मल्टीटास्किंग को लागू करने के लिए आवश्यक होते हैं। विशेष निर्देशों के उदाहरण SPARC विज़ुअल निर्देश समुच्चय, Intel MMX (इंस्ट्रक्शन सेट) और स्ट्रीमिंग SIMD एक्सटेंशन और Motorola Altivec इंस्ट्रक्शन सेट में पाए जाते हैं।
- विशेष कॉलिंग सम्मेलनों तक पहुंच अभी तक संकलक द्वारा समर्थित नहीं है।
- सिस्टम कॉल और इंटरप्ट: उच्च-स्तरीय भाषाओं में शायद ही कभी मनमानी सिस्टम कॉल करने की सीधी सुविधा होती है, इसलिए असेंबली कोड का उपयोग किया जाता है। प्रत्यक्ष व्यवधान और भी कम ही आपूर्ति किए जाते हैं।
- लिंकर या असेंबलर के लिए विशेष निर्देशों का उत्सर्जन करने के लिए, उदाहरण के लिए सेक्शनिंग, मैक्रोज़ को बदलने या प्रतीक उपनाम बनाने के लिए।
दूसरी ओर, इनलाइन असेंबलर कंपाइलर के लिए एक सीधी समस्या बन जाता है क्योंकि यह विश्लेषण को जटिल बनाता है कि प्रत्येक चर के लिए क्या किया जाता है, जो रजिस्टर आवंटन का एक महत्वपूर्ण हिस्सा है।[2] इसका मतलब है कि प्रदर्शन वास्तव में घट सकता है। इनलाइन असेंबलर भविष्य में पोर्टिंग और प्रोग्राम के रखरखाव को भी जटिल बनाता है।[1]
कंपाइलर और प्रोग्रामर दोनों के लिए काम को सरल बनाने के तरीके के रूप में वैकल्पिक सुविधाएं अक्सर प्रदान की जाती हैं। विशेष निर्देशों के लिए आंतरिक कार्य अधिकांश कंपाइलरों द्वारा प्रदान किए जाते हैं और मनमाना सिस्टम कॉल के लिए सी-फंक्शन रैपर हर यूनिक्स प्लेटफॉर्म पर उपलब्ध हैं।
सिंटेक्स
भाषा मानकों में
ISO C++ मानक और ISO C मानक (अनुबंध J) इनलाइन असेंबलर के लिए सशर्त रूप से समर्थित सिंटैक्स निर्दिष्ट करते हैं: <ब्लॉककोट><कविता> एक asm डिक्लेरेशन का फॉर्म है
एएसएम-घोषणा:
asm ( शाब्दिक स्ट्रिंग ) ; एएसएम घोषणा सशर्त समर्थित है; इसका अर्थ कार्यान्वयन-परिभाषित है।[3] </कविता></ब्लॉककोट>
हालांकि, यह परिभाषा वास्तविक सी में शायद ही कभी प्रयोग की जाती है, क्योंकि यह एक साथ बहुत उदार (व्याख्या में) और बहुत प्रतिबंधित है (केवल एक स्ट्रिंग शाब्दिक के उपयोग में)।
वास्तविक संकलक में
व्यावहारिक उपयोग में, मूल्यों पर चलने वाली इनलाइन असेंबली फ्री-फ्लोटिंग कोड के रूप में शायद ही कभी स्टैंडअलोन होती है। चूंकि प्रोग्रामर यह अनुमान नहीं लगा सकता है कि एक चर को किस रजिस्टर को सौंपा गया है, इसलिए कंपाइलर आमतौर पर उन्हें एक एक्सटेंशन के रूप में स्थानापन्न करने का एक तरीका प्रदान करते हैं।
सामान्य तौर पर, C/C++ कंपाइलर द्वारा समर्थित दो प्रकार की इनलाइन असेंबली होती है:
- asm (या __asm__) जीएनयू कंपाइलर संग्रह में। जीसीसी आईएसओ नियमों के प्रत्यक्ष विस्तार का उपयोग करता है: असेंबली कोड टेम्प्लेट स्ट्रिंग्स में लिखा जाता है, जिसमें इनपुट, आउटपुट और क्लोबर्ड रजिस्टरों को कोलन में स्ट्रिंग्स के बाद निर्दिष्ट किया जाता है। सी चर सीधे उपयोग किए जाते हैं जबकि रजिस्टर नाम स्ट्रिंग अक्षर के रूप में उद्धृत किए जाते हैं।[4]
- __asm Microsoft Visual C++ (MSVC), Borland/Embarcadero C कंपाइलर और वंशजों में। यह सिंटैक्स आईएसओ नियमों पर बिल्कुल भी आधारित नहीं है; प्रोग्रामर सी सिंटैक्स के अनुरूप बिना किसी ब्लॉक के अंदर एएसएम लिखते हैं। वेरिएबल्स उपलब्ध हैं जैसे कि वे रजिस्टर हैं और कुछ सी एक्सप्रेशन की अनुमति है।[5] ARM Compiler में इसी तरह की सुविधा हुआ करती थी।[6]
एक्सटेंशन के दो परिवार इनलाइन असेंबली प्रसंस्करण में श्रम विभाजन की अलग-अलग समझ का प्रतिनिधित्व करते हैं। जीसीसी फॉर्म भाषा के समग्र वाक्य-विन्यास को संरक्षित करता है और यह बताता है कि संकलक को क्या जानने की जरूरत है: क्या जरूरत है और क्या बदला है। निर्देश नामों को समझने के लिए संकलक को स्पष्ट रूप से इसकी आवश्यकता नहीं होती है, क्योंकि संकलक को केवल अपने रजिस्टर असाइनमेंट को प्रतिस्थापित करने की आवश्यकता होती है, साथ ही कुछ mov संचालन, इनपुट आवश्यकताओं को संभालने के लिए। हालाँकि, उपयोगकर्ता क्लॉबर्ड रजिस्टरों को गलत तरीके से निर्दिष्ट करने के लिए प्रवण है। एक एम्बेडेड डोमेन-विशिष्ट भाषा का एमएसवीसी फॉर्म लिखने में आसानी प्रदान करता है, लेकिन इसके लिए कंपाइलर को ओपकोड नामों और उनके क्लॉबरिंग गुणों के बारे में जानने की आवश्यकता होती है, रखरखाव और पोर्टिंग में अतिरिक्त ध्यान देने की आवश्यकता होती है।[7] निर्देश सेट के ज्ञान के साथ क्लॉबर गलतियों के लिए जीसीसी-शैली असेंबली की जांच करना अभी भी संभव है।[8] GNAT (GCC सुइट का Ada भाषा फ्रंटएंड), और LLVM GCC सिंटैक्स का उपयोग करता है।[9][10] D प्रोग्रामिंग भाषा आधिकारिक तौर पर x86_64 के लिए MSVC एक्सटेंशन के समान DSL का उपयोग करती है,[11] लेकिन एलएलवीएम-आधारित एलडीसी हर आर्किटेक्चर पर जीसीसी-शैली सिंटैक्स भी प्रदान करता है।[12] एमएसवीसी केवल 32-बिट x86 पर इनलाइन असेंबलर का समर्थन करता है।[5]
रस्ट भाषा तब से एलएलवीएम (जीसीसी-शैली) संस्करण की तुलना में इनलाइन असेंबली विकल्पों को अलग करने वाले सिंटैक्स में माइग्रेट हो गई है। यदि बैकएंड एम्बेडेड असेंबली को हैंडल नहीं कर सकता है तो यह ब्लॉक को बाहरी रूप से असेंबल किए गए फ़ंक्शन में बदलने की अनुमति देने के लिए पर्याप्त जानकारी प्रदान करता है।[7]
उदाहरण
=== जीसीसी === में एक सिस्टम कॉल
एक ऑपरेटिंग सिस्टम को सीधे कॉल करना आम तौर पर सुरक्षित मेमोरी का उपयोग करने वाले सिस्टम के तहत संभव नहीं है। ओएस उपयोगकर्ता (उपयोगकर्ता मोड) की तुलना में अधिक विशेषाधिकार प्राप्त स्तर (कर्नेल मोड) पर चलता है; ऑपरेटिंग सिस्टम के लिए अनुरोध करने के लिए a (सॉफ़्टवेयर) बाधा डालना का उपयोग किया जाता है। उच्च-स्तरीय भाषा में यह शायद ही कभी एक विशेषता है, और इसलिए सिस्टम कॉल के लिए आवरण समारोह इनलाइन असेंबलर का उपयोग करके लिखे गए हैं।
निम्नलिखित सी कोड उदाहरण जीएनयू असेंबलर का उपयोग करके एटी एंड टी सिंटैक्स | एटी एंड टी असेंबलर सिंटैक्स में x86 सिस्टम कॉल रैपर दिखाता है। ऐसी कॉल सामान्यतया मैक्रोज़ की सहायता से लिखी जाती हैं; पूरा कोड स्पष्टता के लिए शामिल किया गया है। इस विशेष मामले में, रैपर कॉल करने वाले द्वारा तीन ऑपरेंड के साथ दिए गए नंबर का एक सिस्टम कॉल करता है, परिणाम लौटाता है।[13] संक्षेप में, जीसीसी बुनियादी और विस्तारित असेंबली दोनों का समर्थन करता है। पूर्व बस कोडांतरक को पाठ शब्दशः पास करता है, जबकि बाद वाला रजिस्टर स्थानों के लिए कुछ प्रतिस्थापन करता है।[4]
<वाक्यविन्यास प्रकाश लैंग = सी> बाहरी int errno;
int syscall3 (int संख्या, int arg1, int arg2, int arg3) {
इंट रेस; __asm__ ( int $0x80 /* OS से अनुरोध करें */ : =a (res), /* रिटर्न परिणाम eax में (ए) */ +b (arg1), /* ebx में arg1 पास करें ( b ) [एक + आउटपुट के रूप में क्योंकि syscall इसे बदल सकता है] */ +c (arg2), /* ecx में arg2 पास करें ( c ) [ditto] */ +d (arg3) /* edx में arg3 पास करें ( d ) [ditto] */ : a (num) /* eax में सिस्टम कॉल नंबर पास करें (a) */ : मेमोरी, सीसी, / * कंपाइलर को घोषणा करें कि मेमोरी और कंडीशन कोड संशोधित किए गए हैं * / ईएसआई, एडी, ईबीपी); /* इन रजिस्टरों को बंद कर दिया गया है [syscall द्वारा बदला गया] भी */
/* ऑपरेटिंग सिस्टम त्रुटि पर एक नकारात्मक मान लौटाएगा; * रैपर त्रुटि पर -1 लौटाते हैं और इरनो ग्लोबल वैरिएबल सेट करते हैं */ अगर (-125 <= रेस && रेस <0) { इरनो = -रेस; रेस = -1; } वापसी रेस;
}
</वाक्यविन्यास हाइलाइट>
x86_64 जैसे आधुनिक आर्किटेक्चर में, syscall का उपयोग करना चाहिए [14]
प्रलेखन में इनपुट सटीक हैं [15]
आर्किटेक्चर के अनुसार रिटर्न वैल्यू दो रजिस्टरों पर हो सकती है
<वाक्यविन्यास लैंग = सी लाइन = 1>
- शामिल <errno.h>
लंबा int syscall3 (अहस्ताक्षरित पूर्णांक संख्या, int arg1, int arg2, int arg3) {
int retA, retB; लंबा इंट रिट; एएसएम (syscall\n\t : = ए (रेटए), = डी (रेटबी) : ए (संख्या), डी (आर्ग3), डी (आर्ग1), एस (आर्ग2) : सीसी, मेमोरी ); रेट = रेटा; / * यहाँ, केवल एक * / अगर (-125 <= ret && ret <0) { इरर्नो = -रेत; रेट = -1; } वापसी रिट;
} </वाक्यविन्यास हाइलाइट>
=== डी === में प्रोसेसर-विशिष्ट निर्देश डी प्रोग्रामिंग लैंग्वेज से इनलाइन असेंबली का यह उदाहरण कोड दिखाता है जो x86 के फ्लोटिंग पॉइंट यूनिट (x87) निर्देशों का उपयोग करके x के स्पर्शरेखा की गणना करता है।
<वाक्यविन्यास प्रकाश लैंग = डी> // x की स्पर्शरेखा की गणना करें असली तन (असली एक्स) {
एएसएम { एफएलडी एक्स [ईबीपी]; // लोड एक्स एफएक्सएएम; // ऑडबॉल मूल्यों के लिए परीक्षण एफएसटीएसडब्ल्यू एएक्स; सहफ; जेसी ट्राइगर; // C0 = 1: x NAN, अनंत या खाली है // 387 डीनॉर्मल्स को संभाल सकते हैं
SC18: fptan;
एफ़एसटीपी एसटी (0); // डंप एक्स, जो हमेशा 1 होता है एफएसटीएसडब्ल्यू एएक्स; सहफ; // if (!(fp_status & 0x20)) गोटो Lret जेएनपी लरेट; // C2 = 1: x सीमा से बाहर है, तर्क में कमी करें एफएलडीपीआई; // लोड पाई एफएक्ससीएच;
SC17: fprem1; // अनुस्मारक (आंशिक)
एफएसटीएसडब्ल्यू एएक्स; सहफ; जेपी एससी 17; // C2 = 1: आंशिक अनुस्मारक, लूप करने की आवश्यकता है एफ़एसटीपी एसटी(1); // पाई को ढेर से हटा दें जेएमपी एससी 18; }
ट्रिगर:
वापसी असली.नान;
Lret: // मैन्युअल रूप से कुछ भी वापस करने की आवश्यकता नहीं है क्योंकि मान पहले से ही FP स्टैक पर है
;
} </वाक्यविन्यास हाइलाइट>
पाठकों के लिए x87 प्रोग्रामिंग से अपरिचित, fstsw-sahf सशर्त कूद मुहावरे के बाद x87 FPU स्थिति शब्द बिट्स C0 और C2 तक पहुँचने के लिए उपयोग किया जाता है। fstsw स्थिति को सामान्य-उद्देश्य रजिस्टर में संग्रहीत करता है; sahf FLAGS रजिस्टर को रजिस्टर के उच्च 8 बिट्स पर सेट करता है; और एफपीयू स्थिति बिट के अनुरूप होने वाले किसी भी ध्वज बिट पर निर्णय लेने के लिए कूद का उपयोग किया जाता है।[16]
संदर्भ
- ↑ 1.0 1.1 "DontUseInlineAsm". GCC Wiki. Retrieved 21 January 2020.
- ↑ Striegel, Ben (13 January 2020). ""To a compiler, a blob of inline assembly is like a slap in the face."". Reddit. Retrieved 15 January 2020.
- ↑ C++, [dcl.asm]
- ↑ 4.0 4.1 "Extended Asm - Assembler Instructions with C Expression Operands". Using the GNU C Compiler. Retrieved 15 January 2020.
- ↑ 5.0 5.1 "Inline Assembler". docs.microsoft.com (in English).
- ↑ "Migration and Compatibility Guide: Inline assembly with Arm Compiler 6".
- ↑ 7.0 7.1 d'Antras, Amanieu (13 December 2019). "Rust RFC-2873: stable inline asm". Retrieved 15 January 2020.
However it is possible to implement support for inline assembly without support from the compiler backend by using an external assembler instead.
Pull Request for status tracking - ↑ "⚙ D54891 [RFC] Checking inline assembly for validity". reviews.llvm.org.
- ↑ "LLVM Language Reference: Inline assembly expressions". LLVM Documentation. Retrieved 15 January 2020.
- ↑ "Inline Assembly". Rust Documentation (1.0.0). Retrieved 15 January 2020.
- ↑ "Inline Assembler". D programming language. Retrieved 15 January 2020.
- ↑ "LDC inline assembly expressions". D Wiki. Retrieved 15 January 2020.
- ↑ Linux Programmer's Manual – System Calls –
- ↑ "Linux System Call Table for x86 64 · Ryan A. Chapman".
- ↑ "Syscall(2) - Linux manual page".
- ↑ "FSTSW/FNSTSW — Store x87 FPU Status Word".
The FNSTSW AX form of the instruction is used primarily in conditional branching...