C Language
इनलाइन असेंबली
खोज…
टिप्पणियों
इनलाइन असेंबली सी स्रोत कोड के बीच में विधानसभा निर्देश जोड़ने का अभ्यास है। कोई आईएसओ सी मानक को इनलाइन असेंबली के समर्थन की आवश्यकता नहीं है। चूंकि इसकी आवश्यकता नहीं है, इनलाइन असेंबली के लिए सिंटैक्स कंपाइलर से कंपाइलर में भिन्न होता है। भले ही यह आम तौर पर समर्थित है, इनलाइन असेंबली का उपयोग करने के बहुत कम कारण हैं और कई कारण नहीं हैं।
पेशेवरों
- प्रदर्शन एक ऑपरेशन के लिए विशिष्ट विधानसभा निर्देश लिखकर, आप संकलक द्वारा उत्पन्न विधानसभा कोड की तुलना में बेहतर प्रदर्शन प्राप्त कर सकते हैं। ध्यान दें कि ये प्रदर्शन लाभ दुर्लभ हैं। ज्यादातर मामलों में आप अपने सी कोड को पुनर्व्यवस्थित करके बेहतर प्रदर्शन लाभ प्राप्त कर सकते हैं ताकि आशावादी अपना काम कर सके।
- हार्डवेयर इंटरफ़ेस डिवाइस ड्राइवर या प्रोसेसर स्टार्टअप कोड को सही रजिस्टरों तक पहुंचने के लिए और संचालन के बीच एक विशिष्ट देरी के साथ एक विशिष्ट क्रम में कुछ संचालन होने की गारंटी देने के लिए कुछ विधानसभा कोड की आवश्यकता हो सकती है।
विपक्ष
- इनलाइन असेंबली के लिए कंपाइलर पोर्टेबिलिटी सिंटैक्स को एक कंपाइलर से दूसरे में समान होने की गारंटी नहीं है। यदि आप इनलाइन असेंबली के साथ कोड लिख रहे हैं जो विभिन्न संकलक द्वारा समर्थित होना चाहिए, तो यह जांचने के लिए कि किस संकलक का उपयोग किया जा रहा है, प्रीप्रोसेसर मैक्रोज़ (
#ifdef
) का उपयोग करें। फिर, प्रत्येक समर्थित संकलक के लिए एक अलग इनलाइन असेंबली अनुभाग लिखें। - प्रोसेसर पोर्टेबिलिटी आप x86 प्रोसेसर के लिए इनलाइन असेंबली नहीं लिख सकते हैं और यह अपेक्षा कर सकते हैं कि यह एआरएम प्रोसेसर पर काम करे। इनलाइन असेंबली का उद्देश्य एक विशिष्ट प्रोसेसर या प्रोसेसर परिवार के लिए लिखा जाना है। यदि आपके पास इनलाइन असेंबली है जिसे आप अलग-अलग प्रोसेसर पर समर्थित चाहते हैं, तो प्रीप्रोसेसर मैक्रोज़ का उपयोग करके यह जांच करें कि किस कोड के लिए कोड संकलित किया जा रहा है और उपयुक्त असेंबली कोड सेक्शन का चयन करने के लिए।
- फ्यूचर परफॉर्मेंस चेंज इनलाइन असेंबली में एक निश्चित प्रोसेसर क्लॉक स्पीड के आधार पर देरी की उम्मीद की जा सकती है। यदि प्रोग्राम तेज घड़ी के साथ प्रोसेसर के लिए संकलित किया जाता है, तो असेंबली कोड अपेक्षित रूप से प्रदर्शन नहीं कर सकता है।
gcc बेसिक asm सपोर्ट
Gcc के साथ मूल असेंबली समर्थन में निम्नलिखित सिंटैक्स है:
asm [ volatile ] ( AssemblerInstructions )
जहाँ AssemblerInstructions
दिए गए प्रोसेसर के लिए डायरेक्ट असेंबली कोड है। वाष्पशील खोजशब्द वैकल्पिक है और इसका कोई प्रभाव नहीं है क्योंकि gcc एक मूल asm कथन में कोड का अनुकूलन नहीं करता है। AssemblerInstructions
में कई असेंबली निर्देश हो सकते हैं। यदि आप एक asm दिनचर्या है कि एक सी समारोह के बाहर मौजूद होना चाहिए एक बुनियादी asm बयान का उपयोग किया जाता है। निम्न उदाहरण जीसीसी मैनुअल से है:
/* Note that this code will not compile with -masm=intel */
#define DebugBreak() asm("int $3")
इस उदाहरण में, आप फिर अपने कोड में अन्य स्थानों पर DebugBreak()
उपयोग कर सकते हैं और यह असेंबली इंस्ट्रक्शन int $3
को निष्पादित करेगा। ध्यान दें कि भले ही gcc एक बुनियादी asm स्टेटमेंट में किसी भी कोड को संशोधित नहीं करेगा, लेकिन ऑप्टिमाइज़र अभी भी लगातार asm स्टेटमेंट को इधर-उधर कर सकता है। यदि आपके पास कई विधानसभा निर्देश हैं जो एक विशिष्ट क्रम में होने चाहिए, तो उन्हें एक asm विवरण में शामिल करें।
जीसीसी विस्तारित asm समर्थन
Gcc में विस्तारित asm समर्थन में निम्नलिखित सिंटैक्स है:
asm [volatile] ( AssemblerTemplate
: OutputOperands
[ : InputOperands
[ : Clobbers ] ])
asm [volatile] goto ( AssemblerTemplate
:
: InputOperands
: Clobbers
: GotoLabels)
जहां AssemblerTemplate
कोडांतरक शिक्षा के लिए टेम्पलेट है, OutputOperands
किसी भी सी चर कि विधानसभा कोड के द्वारा संशोधित किया जा सकता है, InputOperands
किसी भी सी इनपुट पैरामीटर के रूप में इस्तेमाल चर हैं, Clobbers
सूची या रजिस्टर कि विधानसभा कोड से संशोधित कर रहे हैं कर रहे हैं, और GotoLabels
असेंबली कोड में किसी भी गोटो स्टेटमेंट लेबल का उपयोग किया जा सकता है।
विस्तारित प्रारूप का उपयोग C फ़ंक्शन के भीतर किया जाता है और इनलाइन असेंबली का अधिक विशिष्ट उपयोग है। नीचे लिनक्स कर्नेल से 16-बिट और एआरएम प्रोसेसर के लिए 32-बिट संख्या को स्वैप करने के लिए एक उदाहरण है:
/* From arch/arm/include/asm/swab.h in Linux kernel version 4.6.4 */
#if __LINUX_ARM_ARCH__ >= 6
static inline __attribute_const__ __u32 __arch_swahb32(__u32 x)
{
__asm__ ("rev16 %0, %1" : "=r" (x) : "r" (x));
return x;
}
#define __arch_swahb32 __arch_swahb32
#define __arch_swab16(x) ((__u16)__arch_swahb32(x))
static inline __attribute_const__ __u32 __arch_swab32(__u32 x)
{
__asm__ ("rev %0, %1" : "=r" (x) : "r" (x));
return x;
}
#define __arch_swab32 __arch_swab32
#endif
प्रत्येक asm खंड इसके इनपुट और आउटपुट पैरामीटर के रूप में चर x
का उपयोग करता है। C फ़ंक्शन तब हेरफेर किए गए परिणाम देता है।
विस्तारित asm प्रारूप के साथ, gcc असेंब ब्लॉक में असेंबली निर्देशों का अनुकूलन उसी नियम के अनुसार कर सकता है जो C कोड को अनुकूलित करने के लिए उपयोग करता है। यदि आप चाहते हैं कि आपका asm सेक्शन अछूता रहे, तो asm सेक्शन के लिए volatile
कीवर्ड का उपयोग करें।
मैक्रोस में gcc इनलाइन असेंबली
हम एक मैक्रो के अंदर असेंबली निर्देश डाल सकते हैं और मैक्रो का उपयोग कर सकते हैं जैसे आप एक फ़ंक्शन को कॉल करेंगे।
#define mov(x,y) \
{ \
__asm__ ("l.cmov %0,%1,%2" : "=r" (x) : "r" (y), "r" (0x0000000F)); \
}
/// some definition and assignment
unsigned char sbox[size][size];
unsigned char sbox[size][size];
///Using
mov(state[0][1], sbox[si][sj]);
C कोड में एम्बेडेड इनलाइन असेंबली निर्देशों का उपयोग करने से प्रोग्राम के रन टाइम में सुधार हो सकता है। यह क्रिप्टोग्राफिक एल्गोरिदम जैसे एईएस जैसी महत्वपूर्ण परिस्थितियों में बहुत मददगार है। उदाहरण के लिए, एईएस एल्गोरिथ्म में एक सरल पारी ऑपरेशन की आवश्यकता होती है, हम सी शिफ्ट सिस्टम >>
साथ डायरेक्ट Rotate Right
असेंबली इंस्ट्रक्शन को स्थानापन्न कर सकते हैं।
'AES256' के कार्यान्वयन में, 'AddRoundKey ()' फ़ंक्शन में हमारे पास कुछ कथन हैं:
unsigned int w; // 32-bit
unsigned char subkey[4]; // 8-bit, 4*8 = 32
subkey[0] = w >> 24; // hold 8 bit, MSB, leftmost group of 8-bits
subkey[1] = w >> 16; // hold 8 bit, second group of 8-bit from left
subkey[2] = w >> 8; // hold 8 bit, second group of 8-bit from right
subkey[3] = w; // hold 8 bit, LSB, rightmost group of 8-bits
/// subkey <- w
वे बस w
से subkey
सरणी में बिट का मान प्रदान करते हैं।
हम तीन बदलाव + असाइन कर सकते हैं और एक असाइनमेंट C अभिव्यक्ति केवल एक असेंबली Rotate Right
ऑपरेशन के साथ।
__asm__ ("l.ror %0,%1,%2" : "=r" (* (unsigned int *) subkey) : "r" (w), "r" (0x10));
अंतिम परिणाम बिल्कुल वही है।