varargs का उपयोग करने वाले कार्यों को आंतरिक रूप से क्या होता है? क्या तर्क खुद ही ढेर पर या किसी अन्य तर्क की तरह ढेर पर संग्रहीत हैं। अगर ढेर पर, यह कैसे काम करता है?परिवर्तनीय लंबाई तर्क सूचियों को कैसे लागू किया जाता है?
उत्तर
सी में, फ़ंक्शन तर्क दोनों को कॉलर फ़ंक्शन द्वारा स्टैक से धक्का दिया जाता है और खींचा जाता है। कॉलर फ़ंक्शन जानता है कि कितने आइटम धक्का दिए गए थे और इसलिए यह कॉल के बाद उन्हें वापस खींचने में भी सक्षम है। कैली केवल printf()
की प्रारूप स्ट्रिंग जैसे अन्य पैरामीटर से तर्कों की संख्या का अनुमान लगा सकता है।
पास्कल में, उदाहरण के लिए, स्टैक पर तर्क कैली द्वारा खींचे जाते हैं। चूंकि कैली को धक्का देने वाली वस्तुओं की संख्या से अवगत नहीं है, यह स्टैक को अपने पिछले राज्य में बहाल नहीं कर सकता है। यही कारण है कि पास्कल में varargs को लागू करना असंभव है।
"सी में, फ़ंक्शन तर्क दोनों को कॉलर फ़ंक्शन द्वारा स्टैक से धक्का दिया जाता है और खींच लिया जाता है।" - यह कार्यान्वयन-निर्भर है। –
@OliCharlesworth यह सच है। मुझे लगता है कि सी को 'cdecl' कॉलिंग कन्वेंशन का उपयोग करने के लिए कॉन्फ़िगर किया गया है, जिसे "x86 आर्किटेक्चर के लिए कई सी सिस्टम द्वारा उपयोग किया जाता है।" (Http://en.wikipedia.org/wiki/X86_calling_conventions#cdecl) –
इसके अलावा, मैं चाहता था कल्पना करें कि पास्कल * के पास varargs हो सकता है, अगर यह इसके बारे में स्मार्ट था --- आप पहली तर्क के रूप में तर्कों की संख्या प्रदान कर सकते हैं, उदाहरण के लिए (और/या स्टैक टॉप)। आपको निश्चित रूप से कार्यान्वयन में सावधान रहना होगा, लेकिन यह करने योग्य हो सकता है। आपके चित्र में –
यह कार्यान्वयन-निर्भर है। लेकिन सबसे अधिक संभावना है कि तर्क स्टैक पर रखा जाता है, एक के बाद एक (डिफ़ॉल्ट तर्क पदोन्नति के बाद)।
va_start
, va_arg
आदि स्टैक के माध्यम से बस एक पॉइंटर चलकर काम करते हैं, और बिट्स को दोबारा परिभाषित करते हैं जो आप पूछते हैं।
संक्षिप्त और मीठा देखें। +1 – cnicutar
जैसा कि पहले उल्लेख किया गया था, यह कार्यान्वयन निर्भर है।
सी बुला सम्मेलन (cdecl
के रूप में जाना जाता है) में, तर्क, उलटे क्रम में ढेर में धकेल दिया जाता है, ताकि:
void myfunc(int one, int two, int three)
स्टैक पर इस तरह दिखेगा के बाद यह कहा जाता है (ढेर ऊपर की ओर बढ़ता है, 0 की ओर):
. . 0x00000000
. .
. .
| current frame |
|----------------|
| return address |
|----------------| ^
| one | | stack
|----------------| | growth
| two | | direction
|----------------| |
| three |
|----------------|
| previous frame |
...
... 0xFFFFFFFF
तो, पहला तर्क लाए गए पहले हो सकता है (क्योंकि हम जानते हैं कि यह स्थान है, यह सिर्फ वापसी पता पहले है), और उम्मीद है कि यह कैसे कई अन्य तर्क मौजूद हैं पर पर्याप्त जानकारी है। उदाहरण के लिए, printf(3)
और संबंधित कार्यों में, अन्य तर्कों के बारे में सभी जानकारी प्रारूप स्ट्रिंग में मौजूद है, जो पहला तर्क है।
संक्षिप्त उत्तर: यह कार्यान्वयन निर्भर है। आप आमतौर पर फ़ाइलों को शामिल करने में मैक्रोज़ पढ़कर क्या हो रहा है इसका एक अनुमान प्राप्त कर सकते हैं। stdarg.h इसका "आधुनिक" रूप है, varargs.h पुराने, बहिष्कृत संस्करण है। चूंकि आपने विशेष रूप से varargs कहा है, varargs.h पढ़ने का प्रयास करें। –
http://www.tenouk.com/Bufferoverflowc/Bufferoverflow3.html इस साइट को –