चूंकि स्टैक पर तर्क पारित किए जाते हैं, va_
"फ़ंक्शंस" (वे मैक्रोज़ के रूप में लागू होने वाले अधिकांश समय होते हैं) बस एक निजी स्टैक पॉइंटर का उपयोग करते हैं। यह निजी स्टैक पॉइंटर va_start
पर दिए गए तर्क से संग्रहीत है, और फिर va_arg
"स्टैक" से तर्कों को "पॉप" करता है क्योंकि यह पैरामीटर को पुन: सक्रिय करता है।
चलें कहते हैं कि तुम तीन मापदंडों के साथ समारोह max
कहते हैं, इस तरह:
max(a, b, c);
max
समारोह के अंदर, ढेर मूल रूप से इस तरह दिखता है:
+-----+
| c |
| b |
| a |
| ret |
SP -> +-----+
SP
असली ढेर सूचक है , और यह वास्तव में a
, b
और c
नहीं है जो ढेर पर उनके मूल्य हैं। ret
वापसी का पता है, जहां कार्य पूरा होने पर कूदना है।
क्या va_start(ap, n)
करता है (अपने समारोह प्रोटोटाइप में n
) तर्क का पता लेने के लिए और है कि अगले तर्क की स्थिति की गणना करता है से है, इसलिए हम एक नए निजी ढेर सूचक मिलती है:
+-----+
| c |
ap -> | b |
| a |
| ret |
SP -> +-----+
जब आप va_arg(ap, int)
का उपयोग करें जो निजी स्टैक पॉइंटर को इंगित करता है, और उसके बाद अगली तर्क पर इंगित करने के लिए निजी स्टैक पॉइंटर को बदलकर इसे "पॉप" करता है। ढेर अब इस तरह दिखते हैं:
+-----+
ap -> | c |
| b |
| a |
| ret |
SP -> +-----+
यह विवरण निश्चित रूप से सरल है, लेकिन सिद्धांत दिखाता है।
स्रोत
2012-09-11 14:13:35
यह वास्तव में काफी मंच-विशिष्ट है, क्योंकि * कई * कॉलिंग सम्मेलन (सामान्य x64, पीपीसी, एआरएम समेत) रजिस्ट्रारों में अपने अधिकांश पैरामीटर पास करते हैं। कई प्लेटफार्म स्टैक पर रिटर्न पता नहीं डालते हैं, एक या दो प्लेटफार्मों में ढेर होते हैं जो नीचे की ओर ऊपर की ओर बढ़ते हैं, और कुछ कॉलिंग सम्मेलन विपरीत क्रम में स्टैक पर तर्क डालते हैं। –
@ स्कीज़: बहुत बढ़िया जवाब !! – Bruce
@DietrichEpp: मुझे पता है। लेकिन उम्मीद है कि यह कुछ मूलभूत बातें प्राप्त करता है। मैंने स्टैक के विभिन्न तरीकों को प्रतिबिंबित करने के जवाब में कुछ नोट्स दिए हैं। फिर भी, संकलक लागू करने के कई अलग-अलग तरीकों को कवर करने में इसका अधिक लंबा जवाब लगेगा। सरल तरीका मैक्रो परिभाषाओं को ढूंढना होगा और देखें कि वे विस्तार करते हैं और उम्मीद है कि कोई डरावना कंपाइलर जादू नहीं चल रहा है। – Skizz