X64 पर चार तर्क रजिस्टर चुनना - संयुक्त राष्ट्र के लिए सामान्य * X / Win64
X86 के बारे में ध्यान रखने वाली चीजों में से एक यह है कि "reg नंबर" एन्कोडिंग के लिए पंजीकृत नाम स्पष्ट नहीं है; निर्देश एन्कोडिंग के संदर्भ में ( MOD R / M बाइट, http://www.c-jump.com/CIS77/CPU/x86/X77_0060_mod_reg_r_m_byte.htm देखें ), क्रम संख्या 0 - 7 इस क्रम में हैं - ?AX
, ?CX
, ?DX
, ?BX
, ?SP
, ?BP
, ?SI
, ?DI
।
इसलिए वापसी मूल्य के लिए ए / सी / डी (0..2 regs) और पहले दो तर्क (जो "शास्त्रीय" 32 बिट __fastcall
सम्मेलन है) चुनना एक तार्किक विकल्प है। जहां तक 64 बिट जाने का सवाल है, "उच्च" रेज का आदेश दिया जाता है, और माइक्रोसॉफ्ट और यूएन * एक्स / लिनक्स दोनों पहले वाले के रूप में R8
/ के लिए गए थे R9
।
ध्यान में रखते हुए कि, के माइक्रोसॉफ्ट के विकल्प RAX
(वापसी मान) और RCX
, RDX
, R8
, R9
(आर्ग [0..3]) एक समझ में आता चयन यदि आप चाहें तो कर रहे हैं चार तर्क के लिए रजिस्टर।
मुझे नहीं पता कि AMD64 UN * X ABI ने RDX
पहले क्यों चुना RCX
।
X64 पर छह तर्क रजिस्टर चुनना - UN * X विशिष्ट
यूआई * एक्स, आरआईएससी आर्किटेक्चर पर, पारंपरिक रूप से रजिस्टरों में पास होने का तर्क दिया है - विशेष रूप से, पहले छह तर्कों के लिए (यही कारण है कि पीपीसी, स्पार्क, एमआईपीएस कम से कम)। जो प्रमुख कारणों में से एक हो सकता है क्यों AMD64 (UN * X) ABI डिजाइनरों ने उस वास्तुकला पर भी छह रजिस्टरों का उपयोग करने के लिए चुना।
तो अगर आप चाहते हैं छह रजिस्टरों में तर्क पारित करने के लिए, और यह चयन करने के लिए तार्किक है RCX
, RDX
, R8
और R9
उनमें से चार, के लिए अन्य दो जो आप चुनना चाहिए?
"उच्च" regs को उन्हें चुनने के लिए एक अतिरिक्त निर्देश उपसर्ग बाइट की आवश्यकता होती है और इसलिए उनके पास एक बड़ा निर्देश आकार पदचिह्न होता है, इसलिए यदि आप विकल्प रखते हैं, तो आप उनमें से कोई भी चुनना नहीं चाहेंगे। शास्त्रीय रजिस्टरों में, इसके निहित अर्थ के कारण RBP
और RSP
ये उपलब्ध नहीं हैं, और RBX
पारंपरिक रूप से UN * X (वैश्विक ऑफसेट तालिका) पर एक विशेष उपयोग होता है, जो प्रतीत होता है कि AMD64 ABI डिजाइनर अनावश्यक रूप से असंगत नहीं बनना चाहते थे।
एर्गो, एकमात्र विकल्प थे RSI
/ RDI
।
इसलिए यदि आपको तर्क रजिस्टर के रूप में RSI
/ लेना है RDI
, तो वे कौन से तर्क होने चाहिए?
उन्हें बनाने arg[0]
और arg[1]
कुछ फायदे हैं। देखें cHao की टिप्पणी
?SI
और ?DI
स्ट्रिंग निर्देश स्रोत / गंतव्य ऑपरेंड हैं, और जैसा कि cHao ने उल्लेख किया है, तर्क रजिस्टरों के रूप में उनके उपयोग का अर्थ है कि AMD64 UN * X कॉलिंग कन्वेंशन के साथ, सबसे सरल संभव strcpy()
फ़ंक्शन, उदाहरण के लिए, केवल दो सीपीयू निर्देश शामिल हैं repz movsb; ret
क्योंकि स्रोत / लक्ष्य कॉलर द्वारा सही रजिस्टरों में पते डाले गए हैं। विशेष रूप से निम्न-स्तरीय और संकलक-जनरेट किए गए "गोंद" कोड में है (उदाहरण के लिए, सोचिए, कुछ C ++ हीप एलोकेटर निर्माण पर शून्य-भरने वाली वस्तुओं, या कर्नेल शून्य-भरने वाले ढेर पृष्ठों कोsbrk()
, या कॉपी-ऑन-राइट पेजफॉल्ट्स) एक बड़ी मात्रा में ब्लॉक कॉपी / भरते हैं, इसलिए यह कोड के लिए उपयोगी होगा, इसलिए दो या तीन सीपीयू निर्देशों को बचाने के लिए अक्सर उपयोग किया जाता है जो अन्यथा ऐसे स्रोत / लक्ष्य पते के तर्कों को लोड करते हैं "सही" रजिस्टर।
तो एक तरह से, संयुक्त राष्ट्र * एक्स और Win64 में है कि संयुक्त राष्ट्र * एक्स "पहले जोड़ता है" दो अतिरिक्त तर्क, उद्देश्यपूर्ण चुना में केवल अलग हैं RSI
/ RDI
रजिस्टर, में चार तर्कों की स्वाभाविक पसंद करने के लिए RCX
, RDX
, R8
और R9
।
उस परे ...
विशिष्ट रजिस्टरों के लिए तर्कों के मानचित्रण की तुलना में UN * X और Windows x64 ABI के बीच अधिक अंतर हैं। Win64 पर अवलोकन के लिए, देखें:
http://msdn.microsoft.com/en-us/library/7kcdt6fy.aspx
Win64 और AMD64 UN * X स्ट्राइकस्पेस के उपयोग करने के तरीके में भी अलग-अलग हैं; Win64 पर, उदाहरण के लिए, कॉल करने वाले को फ़ंक्शन तर्कों के लिए स्टैकस्पेस आवंटित करना चाहिए , भले ही args 0 ... 3 रजिस्टरों में पारित हो। दूसरी ओर UN * X पर, एक लीफ फंक्शन (यानी जो अन्य कार्यों को कॉल नहीं करता है) को स्टैकस्पेस को आवंटित करने की भी आवश्यकता नहीं है, अगर इसे 128 बाइट्स से अधिक की आवश्यकता नहीं है (हाँ, आप स्वयं और उपयोग कर सकते हैं इसे आवंटित किए बिना स्टैक की एक निश्चित मात्रा ... ठीक है, जब तक कि आप कर्नेल कोड नहीं हैं, निफ्टी बग का स्रोत है)। ये सभी विशेष रूप से अनुकूलन विकल्प हैं, उन लोगों के लिए तर्क के अधिकांश को पूर्ण एबीआई संदर्भों में समझाया गया है जो मूल पोस्टर के विकिपीडिया संदर्भ को इंगित करता है।