Disassembler command और main फ़ंक्शन के छिपे हुए तथ्य।7 min read

Disassembler डिबगिंग के लिए बहुत उपयोगी है। यह ट्यूटोरियल EFL फ़ाइल फॉर्मेट और disassembler command के संबंध में जानकारी प्रदान करेगा। main फ़ंक्शन के कुछ छिपे हुए तथ्यों पर एक ऐड-ऑन के रूप में उदाहरणों के साथ समझाया गया है।

To read this article in English, click here!

ELF फ़ाइल फार्मेट के बारे में जानें।

EFL फ़ाइल फॉर्मेट क्या है?

  • EFL का अर्थ है “निष्पादन योग्य और जोड़ने योग्य प्रारूप(Executable and Linkable Format)” (EFL, जिसे पहले एक्स्टेंसिबल लिंकिंग फॉर्मेट (Extensible Linking Format) नाम दिया गया था)।
  • यह निष्पादन योग्य फ़ाइल, ऑब्जेक्ट कोड, शेयर्ड लिब्ररिए और कोर डंप के लिए एक सामान्य मानक फ़ाइल फॉर्मेट है।

अधिक आप इसके बारे में यहाँ पढ़ सकते हैं!


Disassembler command

डिस्सेम्बलर (disassembler) एक कंप्यूटर कोड है जो मशीन लैंग्वेज (बाइनरी कोड) को असेंबली लैंग्वेज में ट्रांसलेट करता है। सरल शब्दों में यह एक असेंबलर का उलटा ऑपरेशन है।

Hex संपादकों (Disassembler): जो बाइनरी कोड को असेंबली कोड में कनवर्ट करता है

COMMAND: objdump (ऑब्जेक्ट डंप)

objdump डिफ़ॉल्ट रूप से UNIX / Linux Disassembler में उपलब्ध है। जिसे मुख्य रूप से Disassembler का उपयोग करके ऑब्जेक्ट फ़ाइल (बाइनरी फ़ाइल) को संपादित करने के लिए उपयोग किया जाता है।

ऑब्जेक्ट फ़ाइल निर्माण के बारे में जानने के लिए यहां क्लिक करें!

लिनक्स में objdump कमांड का उपयोग ऑब्जेक्ट फाइल की विस्तार से जानकारी प्राप्त करने के लिए किया जाता है।

यह कमांड मुख्य रूप से कंपाइलर प्रोग्रामर द्वारा उपयोग किया जाता है, लेकिन फिर भी, यह सामान्य प्रोग्रामर के लिए कोड को डिबगिंग के लिए भी एक उपयोगी उपकरण है।

Syntax:

$ objdump [options] <object file>...

उदाहरण के लिए।

$ objdump -D prog.o
Direct use of Disassembler command obj dump code is not giving user friendly output

यह कैसे objdump आउटपुट देता है। यह सीधे आपको नीचे ले जाता है उपयोगकर्ता के लिए ये अनुकूल मार्ग नहीं है।

समस्या का अर्थ है एक समाधान।

समाधान:

यदि आप पेज वार डिस्प्ले में आउटपुट चाहते हैं तो “less” या “more” कमांड का उपयोग करें।

अतिरिक्त जानकारी- “|” यह एक पाइप है (हम लिनक्स ट्यूटोरियल में सीखेंगे)।

उदाहरण के लिए।

$ objdump -D prog.o | less

अथवा

$ objdump -D prog.o | more

पथ प्रदर्शन:

W = एक पृष्ठ ऊपर जाओ

D = एक पृष्ठ नीचे जाओ

S = एक पंक्ति नीचे

या आप कीबोर्ड की “पेज डाउन” और “पेज अप” बटन और “तीर कुंजियों” का उपयोग कर सकते हैं।

Q = पृष्ठ दृश्य छोड़ने के लिए

Less and more command use

जब आप ऑब्जेक्ट फ़ाइल को अलग कर लेते हैं, तो आप देख सकते हैं कि प्रोग्राम निष्पादन स्टार्टअप फ़ंक्शन से शुरू होता है, जिसमें स्टार्टअप फ़ंक्शन मुख्य फ़ंक्शन को कहा जाता है और स्टार्टअप फ़ंक्शन को मुख्य निष्पादन और रिटर्न देता है।

नोट: main फंक्शन को केवल स्टार्टअप फ़ंक्शन ही कॉल करता है, स्टार्टअप फ़ंक्शन को main फंक्शन रिटर्न देता है, इसलिए हम main फ़ंक्शन को कभी कॉल नहीं करते, यह केवल स्टार्टअप फ़ंक्शन द्वारा ही किया जा सकता है।


प्रश्न) ऑब्जेक्ट फ़ाइल और निष्पादन योग्य फ़ाइलों का माप भिन्न क्यों हैं?

$ size prog.o
Performed size command on prog.o file
$ size prog
performed size command on prog file

prog.o ऑब्जेक्ट फ़ाइल हमारे लिखित मुख्य कोड के ऑब्जेक्ट कोड के अलावा कुछ भी नहीं है। जबकि निष्पादन योग्य फ़ाइल prog फ़ाइल लिंकर द्वारा बनाई गई है; लिंकर का कार्य OS समर्थित फ़ाइलों और अन्य ऑब्जेक्ट फ़ाइलों को इससे लिंक करना है।


दिलचस्प main() फ़ंक्शन।

यदि रिटर्न प्रकार का उल्लेख नहीं किया गया है, तो डिफ़ॉल्ट रिटर्न प्रकार int होगा, लेकिन कुछ संकलक चेतावनी फेंक देंगे और चेतावनी कष्टप्रद है।

main( ) == int main( ) == main(void) == int main(void)

निजी राय:

हमेशा एक अच्छी आदतों से शुरुआत करें।

<return type> function name (arguments)

यह एक फ़ंक्शन का प्रोटोटाइप है और अगर हम अनुसरण करते हैं, तो भविष्य में यह बहुत मददगार होगा।

भविष्य में हम इसका कारण देखेंगे। मुख्य में भी आर्ग्यूमेंट्स होते हैं और कभी-कभी हम आर्ग्यूमेंट्स लिखना भूल जाते हैं और अनावश्यक डिबगिंग कार्य करते हैं। यह एक समर्थक बिंदु है।

main () हमेशा एक कॉलिंग फंक्शन होता है।

सरल शब्दों में हम कोड में main() को कॉल नहीं कह सकते।

प्रोग्राम का एक्सेक्यूशन main फंक्शन से चालू होता है और main फंक्शन पर ही ख़तम होता है।


लेकिन क्या होगा अगर मैं कोड में main() का उपयोग नहीं करते?

इसकी जांच करें:

This is our source code test.c

यह हमारा test.c सोर्स कोड है।

proprocessor stage is also passed without error

हमारा सोर्स कोड प्रीप्रोसेसर स्टेज से गुजरा है, इसका मतलब कोई त्रुटि नहीं है।

No error in Translator stage

हमारे सोर्स कोड ने अनुवादक चरण पारित किया, इसका मतलब है कि कोई त्रुटि नहीं है।

Assembler stage also passed

हमारे सोर्स कोड ने असेंबलर चरण पारित किया, इसका मतलब है कि कोई त्रुटि नहीं है।

In linker stage code thrown an error

वाह! लिंकर ने एक त्रुटि डाली है। त्रुटि पाई गई क्योंकि लिंकर स्टार्टअप फ़ंक्शन में main() नहीं मिला है। चलो इसे छोटे टुकड़ों में तोड़ दें।

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

भाग 1:

Undefined symbols for architecture x86_64:
  "_main", referenced from:
     implicit entry/start for main executable
ld: symbol(s) not found for architecture x86_64

x86 आर्किटेक्चर में _Main एक implicit कार्य है। implicit का एक अर्थ क्या है?

definition of implicit function

भाग 2:

clang: error: linker command failed with exit code 1 (use -v to see invocation)

तो परिभाषा के अनुसार मुख्य कार्य होना चाहिए। इसीलिए लिंकर कोड 1 से बाहर निकल गया।

समाधान:

हर लिंकर main() के साथ निष्पादन (execution) शुरू करता है।

लिंकिंग त्रुटि को दूर करने के लिए निम्नलिखित कमांड का उपयोग करें।

$ gcc -nostartfiles test.c
-nostartfiles working

अगर आपको यह आर्टिकल पसंद आया हे तो अपने विचार कमेंट करके हमें प्रेरित करे।

Leave a Comment