Windows86 x86-64 पर अन्य सभी ओएस से अलग कॉलिंग कन्वेंशन का उपयोग क्यों करता है?


110

एएमडी में एक एबीआई विनिर्देश है जो x86-64 पर उपयोग करने के लिए कॉलिंग सम्मेलन का वर्णन करता है। सभी ओएस इसका अनुसरण करते हैं, विंडोज को छोड़कर, जिसमें स्वयं x86-64 कॉलिंग कन्वेंशन है। क्यों?

क्या कोई इस अंतर के तकनीकी, ऐतिहासिक या राजनीतिक कारणों को जानता है, या यह विशुद्ध रूप से NIHsyndrome का मामला है?

मैं समझता हूं कि उच्च स्तर की चीजों के लिए विभिन्न ओएस की अलग-अलग आवश्यकताएं हो सकती हैं, लेकिन यह नहीं बताता है कि उदाहरण के लिए विंडोज पर रजिस्टर पैरामीटर पासिंग ऑर्डर क्यों है rcx - rdx - r8 - r9 - rest on stackजबकि बाकी सभी का उपयोग करता है rdi - rsi - rdx - rcx - r8 - r9 - rest on stack

PS मुझे पता है कि ये कॉलिंग कन्वेंशन आम तौर पर कैसे भिन्न होते हैं और मुझे पता है कि अगर मुझे ज़रूरत है तो विवरण कहाँ खोजना है। मैं जानना चाहता हूं कि ऐसा क्यों है

संपादित करें: कैसे के लिए, वहाँ से विकिपीडिया प्रविष्टि और लिंक देखें।


2
ठीक है, सिर्फ पहले रजिस्टर के लिए: rcx: ecx msvc __thiscall x86 हस्तक्षेप के लिए "यह" पैरामीटर था। तो शायद x64 में अपने संकलक को पोर्ट करने में आसानी के लिए, उन्होंने आरसीएक्स के साथ शुरुआत की। फिर बाकी सब कुछ भी अलग होगा जो उस प्रारंभिक निर्णय का परिणाम था।
क्रिस बेके

@ क्रिस: मैंने नीचे AMD64 ABI पूरक दस्तावेज (और कुछ स्पष्टीकरण जो यह वास्तव में है) का संदर्भ जोड़ा है।
फ्रैंक।

1
मुझे एमएस से औचित्य नहीं मिला है, लेकिन मुझे यहां
फुकुव

जवाबों:


81

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 बाइट्स से अधिक की आवश्यकता नहीं है (हाँ, आप स्वयं और उपयोग कर सकते हैं इसे आवंटित किए बिना स्टैक की एक निश्चित मात्रा ... ठीक है, जब तक कि आप कर्नेल कोड नहीं हैं, निफ्टी बग का स्रोत है)। ये सभी विशेष रूप से अनुकूलन विकल्प हैं, उन लोगों के लिए तर्क के अधिकांश को पूर्ण एबीआई संदर्भों में समझाया गया है जो मूल पोस्टर के विकिपीडिया संदर्भ को इंगित करता है।


1
रजिस्टर नामों के बारे में: वह उपसर्ग बाइट एक कारक हो सकता है। लेकिन तब MS के लिए rcx - rdx - rdi - rsi को तर्क रजिस्टरों के रूप में चुनना अधिक तर्कसंगत होगा। यदि आप ABI को खरोंच से डिज़ाइन कर रहे हैं, लेकिन पहले आठ का संख्यात्मक मान आपको निर्देशित कर सकता है, लेकिन यदि कोई बिलकुल ठीक ABI पहले से मौजूद है, तो उन्हें बदलने का कोई कारण नहीं है, जो केवल अधिक भ्रम पैदा करता है।
जनकिनी

2
RSI / RDI पर: ये निर्देश आमतौर पर इनलेट होंगे, जिसमें कन्वेंशन को बुलाना मायने नहीं रखता। अन्यथा, वहाँ कि समारोह सिस्टमवाइड की केवल एक प्रतिलिपि (या शायद कुछ) है, तो यह केवल बाइट्स की एक handfull बचाता कुल में । इसके लायक नहीं। अन्य अंतरों / कॉल स्टैक पर: एबीआई संदर्भों में विशिष्ट विकल्पों की उपयोगिता को समझाया गया है, लेकिन वे तुलना नहीं करते हैं। वे यह नहीं बताते हैं कि अन्य अनुकूलन क्यों नहीं चुने गए - जैसे कि विंडोज में 128 बाइट रेड ज़ोन क्यों नहीं है, और एएमडी एबीआई में तर्कों के लिए अतिरिक्त स्टैक स्लॉट क्यों नहीं हैं?
जनकिनी

1
@cHao: नहीं। लेकिन उन्होंने इसे वैसे भी बदल दिया। Win64 ABI Win32 एक (और संगत नहीं) से अलग है, और AMDs ABI से भी अलग है।
जनकिनी

7
@ सोमजन: Win64 और Win32 __fastcallदो प्रतिशत से अधिक नहीं होने के मामले में 100% समान हैं, जो 32bit से बड़ा नहीं है और मान 32bit से बड़ा नहीं है। यह कार्यों का एक छोटा वर्ग नहीं है। I386 / amd64 के लिए UN * X ABIs के बीच ऐसी कोई पिछड़ी संगतता संभव नहीं है।
फ्रैंक।

2
@szx: मुझे सिर्फ प्रासंगिक मेलिंग लिस्ट थ्रेड नवंबर 2000 से मिली, और उसने एक उत्तर दिया, जिसमें तर्क का वर्णन किया गया था। ध्यान दें कि यह memcpyउस तरह से लागू किया जा सकता है, नहीं strcpy
पीटर कॉर्ड्स

42

IDK क्यों विंडोज ने किया उन्होंने क्या किया। एक अनुमान के लिए इस उत्तर का अंत देखें। मैं इस बारे में उत्सुक था कि SysV कॉलिंग कन्वेंशन कैसे तय किया गया था, इसलिए मैंने मेलिंग सूची संग्रह में खोदा और कुछ साफ-सुथरा सामान पाया।

यह दिलचस्प है कि AMD64 मेलिंग सूची में उन पुराने धागों में से कुछ पढ़ रहे हैं, क्योंकि AMD आर्किटेक्ट उस पर सक्रिय थे। उदाहरण के लिए रजिस्टर नाम चुनना कठिन भागों में से एक था: AMD को मूल 8 रजिस्टरों r0-r7 का नाम बदलने या नए रजिस्टर सामान की तरह कॉल करने पर विचार किया गयाUAX

इसके अलावा, कर्नेल देवों के फीडबैक ने उन चीजों की पहचान की, जो मूल डिजाइन syscallऔर swapgsअनुपयोगी हैं । कि किसी भी वास्तविक चिप्स को जारी करने से पहले एएमडी ने इसे कैसे हल करने के निर्देश को अपडेट किया । यह भी दिलचस्प है कि 2000 के अंत में, यह धारणा थी कि इंटेल शायद AMD64 को नहीं अपनाएगा।


SysV (लिनक्स) कॉलिंग कन्वेंशन, और कितने रजिस्टरों को कैली-संरक्षित बनाम कॉलर-सेव किया जाना चाहिए, इस निर्णय को शुरू में जनवरी 2000 में जन हुबिका (एक जीसीसी डेवलपर) द्वारा किया गया था। उन्होंने Spec2000 को संकलित किया और कोड आकार और निर्देशों की संख्या को देखा। यह चर्चा धागा इस SO प्रश्न पर उत्तरों और टिप्पणियों के समान कुछ विचारों के आसपास उछलता है। 2 थ्रेड में, उन्होंने वर्तमान अनुक्रम को इष्टतम और उम्मीद के मुताबिक अंतिम रूप से प्रस्तावित किया, कुछ विकल्पों की तुलना में छोटे कोड का निर्माण किया

वह "ग्लोबल" शब्द का उपयोग कॉल-संरक्षित रजिस्टरों का मतलब करने के लिए कर रहा है, जिसका उपयोग होने पर धक्का / पॉपअप करना होगा।

के चुनाव rdi, rsi, rdxके रूप में पहले तीन आर्ग से प्रेरित हुआ:

  • उन कार्यों में मामूली कोड-आकार की बचत जो कि memsetउनके आर्ग पर कॉल या अन्य सी स्ट्रिंग फ़ंक्शन (जहां जीसीसी एक प्रतिनिधि स्ट्रिंग ऑपरेशन को रेखांकित करता है?)
  • rbxकॉल-संरक्षित है क्योंकि REX उपसर्गों (आरबीएक्स और आरबीपी) के बिना दो कॉल-संरक्षित regs सुलभ होना एक जीत है। संभवतया इसलिए चुना गया क्योंकि यह एकमात्र अन्य रेज है जिसका किसी भी निर्देश द्वारा उपयोग नहीं किया गया है। (प्रतिनिधि स्ट्रिंग, पारी की गिनती, और mul / div outputs / आदानों सब कुछ स्पर्श)।
  • विशेष उद्देश्यों के साथ रजिस्टरों में से कोई भी कॉल-संरक्षित (प्रचलित बिंदु देखें), इसलिए एक फ़ंक्शन जो प्रतिनिधि स्ट्रिंग निर्देशों का उपयोग करना चाहता है या एक वैरिएबल-काउंट शिफ्ट को फ़ंक्शन आर्ग को कहीं और स्थानांतरित करना पड़ सकता है, लेकिन उसे सहेजना नहीं है / कॉलर का मान पुनर्स्थापित करें।
  • हम अनुक्रम में आरसीएक्स से जल्दी से बचने की कोशिश कर रहे हैं, क्योंकि यह आमतौर पर ईएक्सएक्स जैसे विशेष उद्देश्यों के लिए उपयोग किया जाता है, इसलिए इसका अनुक्रम में गायब होने का एक ही उद्देश्य है। इसके अलावा यह syscalls के लिए इस्तेमाल नहीं किया जा सकता है और हम फ़ंक्शन कॉल अनुक्रम को यथासंभव मिलान करने के लिए syscall अनुक्रम बनाना चाहते हैं।

    (पृष्ठभूमि: syscall/ sysretअपरिहार्य रूप से नष्ट rcx( rip) के साथ और r11(साथ RFLAGS), इसलिए कर्नेल यह नहीं देख सकता कि मूल रूप से rcxकब syscallभाग गया था।)

कर्नेल सिस्टम-कॉल ABI को r10इसके बजाय फ़ंक्शन कॉल ABI से मेल खाने के लिए चुना गया था rcx, इसलिए एक libc आवरण कार्य जैसे / / mmap(2)कर सकते हैं ।mov %rcx, %r10mov $0x9, %eaxsyscall


ध्यान दें कि विंडो के 32 बिट __vectorcall की तुलना में i386 लिनक्स द्वारा प्रयुक्त SysV कॉलिंग कन्वेंशन। यह स्टैक पर सब कुछ गुजरता है, और केवल edx:eaxint64 के लिए लौटता है , छोटी संरचनाओं के लिए नहीं । यह कोई आश्चर्य की बात नहीं है कि इसके साथ संगतता बनाए रखने के लिए बहुत कम प्रयास किया गया था। जब कोई कारण नहीं है, तो उन्होंने rbxकॉल-संरक्षित रखने जैसी चीजें कीं , क्योंकि उन्होंने फैसला किया कि मूल 8 में एक और होने (जिसे REX उपसर्ग की आवश्यकता नहीं है) अच्छा था।

एबीआई इष्टतम बनाना है बहुत अधिक महत्वपूर्ण किसी अन्य विचार से लंबी अवधि के। मुझे लगता है कि उन्होंने बहुत अच्छा काम किया। मैं विभिन्न रजिस्टरों में अलग-अलग क्षेत्रों के बजाय, रजिस्टरों में पैक किए गए स्ट्रक्चर को वापस करने के बारे में पूरी तरह सुनिश्चित नहीं हूं। मुझे लगता है कि कोड है कि उन्हें वास्तव में इस तरह से जीतता है बिना खेतों के आसपास मूल्य से गुजरता है, लेकिन unpacking के अतिरिक्त काम मूर्खतापूर्ण लगता है। उनके पास अधिक पूर्णांक रिटर्न रजिस्टर हो सकते थे, बस से अधिक rdx:rax, इसलिए 4 सदस्यों के साथ एक संरचना को वापस करके उन्हें rdi, rsi, rdx, rax या कुछ में वापस किया जा सकता था।

वे वेक्टर रेज में पूर्णांक पास करने पर विचार करते हैं, क्योंकि SSE2 पूर्णांक पर काम कर सकते हैं। सौभाग्य से उन्होंने ऐसा नहीं किया। इंटेगर का उपयोग अक्सर पॉइंटर ऑफ़सेट के रूप में किया जाता है, और स्टैक मेमोरी के लिए एक गोल-यात्रा बहुत सस्ती है । इसके अलावा SSE2 निर्देश पूर्णांक निर्देशों की तुलना में अधिक कोड बाइट लेते हैं।


मुझे संदेह है कि Windows ABI डिज़ाइनर लोगों के लाभ के लिए 32 और 64bit के बीच के अंतर को कम करने का लक्ष्य रख सकते हैं, जिन्हें एक से दूसरे में asm पोर्ट करना है, या जो कि #ifdefकुछ ASM में एक जोड़े का उपयोग कर सकते हैं ताकि एक ही स्रोत अधिक आसानी से बना सकें किसी फ़ंक्शन का 32 या 64 बिट संस्करण।

टूलकिन में कम से कम परिवर्तन संभव नहीं लगता है। एक x86-64 कंपाइलर को एक अलग टेबल की आवश्यकता होती है, जिसके लिए रजिस्टर का उपयोग किसके लिए किया जाता है, और कॉलिंग कन्वेंशन क्या है। 32 बिट के साथ एक छोटे से ओवरलैप होने से टूलकिन कोड आकार / जटिलता में महत्वपूर्ण बचत का उत्पादन करने की संभावना नहीं है।


1
मुझे लगता है कि मैंने एमएस की तरफ से बेंचमार्किंग के बाद उन रजिस्टरों को चुनने के औचित्य के बारे में रेमंड चेन के ब्लॉग पर कहीं पढ़ा है, लेकिन मुझे यह अब नहीं मिल रहा है। हालाँकि होमजोन के संबंध में कुछ कारणों के बारे में यहाँ बताया गया है। blogs.msdn.microsoft.com/oldnewthing/20160623-00/?p=93735 blogs.msdn.microsoft.com/freik/2006/03/06/…
यूक्लूव


@phuclv: यह भी देखें कि क्या ESP के नीचे लिखना मान्य है? । मेरे जवाब पर रेमंड की टिप्पणियों ने कुछ SEH विवरणों की ओर इशारा किया, जो मुझे नहीं पता था कि यह क्यों समझाता है कि x86 32/64 विंडोज में वर्तमान में डी-फैक्टो रेड ज़ोन नहीं है। उनके ब्लॉग पोस्ट में एक ही कोड पेज-इन हैंडलर संभावना के लिए कुछ प्रशंसनीय मामले हैं, जिनका मैंने उस उत्तर में उल्लेख किया है :) तो, हाँ, रेमंड ने मुझे समझाने की तुलना में इसे करने का एक बेहतर काम किया (अस्वाभाविक रूप से क्योंकि मैं विंडोज से बहुत कम जानने के बाद शुरू हुआ था, और गैर- x86 के लिए लाल-ज़ोन आकार की तालिका वास्तव में साफ है।
पीटर कॉर्डेस

13

याद रखें कि माइक्रोसॉफ्ट शुरू में "प्रारंभिक AMD64 प्रयास की ओर आधिकारिक तौर पर गैर-विवादास्पद था" ( मैथ्यू कर्नर और नील पडगेट द्वारा "आधुनिक 64-बिट कम्प्यूटिंग का इतिहास" से) क्योंकि वे IA64 वास्तुकला पर इंटेल के साथ मजबूत भागीदार थे। मुझे लगता है कि इसका मतलब यह था कि भले ही वे अन्यथा यूनिक्स और विंडोज दोनों पर उपयोग करने के लिए एबीआई पर जीसीसी इंजीनियरों के साथ काम करने के लिए खुले थे, उन्होंने ऐसा नहीं किया होगा क्योंकि इसका मतलब सार्वजनिक रूप से AMD64 प्रयास का समर्थन करना होगा जब वे नहीं थे ' टी अभी तक आधिकारिक तौर पर ऐसा किया है (और शायद इंटेल को परेशान करेगा)।

शीर्ष पर, उन दिनों में Microsoft के पास ओपन सोर्स प्रोजेक्ट्स के अनुकूल होने की दिशा में बिल्कुल झुकाव नहीं था। निश्चित रूप से लिनक्स या जीसीसी नहीं।

तो वे एक एबीआई पर सहयोग क्यों करेंगे? मुझे लगता है कि एबीआई अलग-अलग हैं, क्योंकि वे एक ही समय में और कम से कम और अलगाव में डिजाइन किए गए थे।

"आधुनिक 64-बिट कम्प्यूटिंग का इतिहास" से एक और उद्धरण:

Microsoft सहयोग के समानांतर, एएमडी ने चिप की तैयारी के लिए खुले स्रोत समुदाय को भी शामिल किया। AMD उपकरण श्रृंखला के काम के लिए कोड सॉर्सेरी और SuSE दोनों के साथ अनुबंध किया (Red Hat पहले से ही IA64 टूल पोर्ट पोर्ट पर Intel द्वारा लगा हुआ था)। रसेल ने बताया कि SuSE ने C और FORTRAN कंपाइलरों का उत्पादन किया और कोड सोरसेरी ने पास्कल कंपाइलर का उत्पादन किया। वेबर ने समझाया कि लिनक्स पोर्ट को तैयार करने के लिए कंपनी लिनक्स समुदाय से भी जुड़ी है। यह प्रयास बहुत महत्वपूर्ण था: इसने माइक्रोसॉफ्ट के लिए AMD64 विंडोज प्रयास में निवेश जारी रखने के लिए एक प्रोत्साहन के रूप में काम किया, और यह भी सुनिश्चित किया कि लिनक्स, जो उस समय एक महत्वपूर्ण ओएस बन रहा था, चिप्स जारी होने के बाद उपलब्ध होगा।

वेबर यह कहते हुए यहां तक ​​जाता है कि लिनक्स का काम एएमडी 64 की सफलता के लिए बहुत महत्वपूर्ण था, क्योंकि इसने एएमडी को आवश्यक होने पर किसी भी अन्य कंपनियों की मदद के बिना एंड-टू-एंड सिस्टम का उत्पादन करने में सक्षम बनाया। इस संभावना ने सुनिश्चित किया कि एएमडी के पास सबसे खराब स्थिति की जीवित रहने की रणनीति थी, भले ही अन्य भागीदारों ने समर्थन किया हो, जो बदले में अन्य भागीदारों को अपने पीछे छोड़ दिए जाने के डर से लगे रहे।

यह इंगित करता है कि यहां तक ​​कि एएमडी को यह महसूस नहीं हुआ कि एमएस और यूनिक्स के बीच सहयोग सबसे जरूरी था, लेकिन यह कि यूनिक्स / लिनक्स समर्थन बहुत महत्वपूर्ण था। हो सकता है कि समझौता करने या सहयोग करने के लिए एक या दोनों पक्षों को समझाने का प्रयास भी उनमें से किसी को परेशान करने के प्रयास या जोखिम (?) के लायक नहीं था? शायद एएमडी ने सोचा कि एक आम एबीआई का सुझाव भी देरी कर सकता है या चिप तैयार होने पर बस सॉफ्टवेयर सपोर्ट तैयार करने के अधिक महत्वपूर्ण उद्देश्य को प्राप्त कर सकता है।

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


राजनीति पर अच्छा दृष्टिकोण। मैं सहमत हूं कि यह एएमडी की गलती या जिम्मेदारी नहीं है। मैं एक बदतर कॉलिंग कन्वेंशन चुनने के लिए Microsoft को दोष देता हूं। अगर उनकी कॉलिंग कन्वेंशन बेहतर हो जाती, तो मुझे कुछ सहानुभूति होती, लेकिन उन्हें अपने शुरुआती एबीआई से बदलना पड़ा __vectorcallक्योंकि __m128स्टैक को चूसने पर पास होना। वेक्टर वेक्टर में से कुछ के कम 128b के लिए कॉल-संरक्षित शब्दार्थ भी अजीब है (आंशिक रूप से इंटेल का एसएसई के साथ एक एक्स्टेंसिबल सेव / रिस्टोर मैकेनिज्म को डिजाइन नहीं करने के लिए गलती है, और अभी भी एवीएक्स के साथ नहीं है।)
पीटर कॉर्ड्स ने

1
मेरे पास वास्तव में कोई विशेषज्ञता या ज्ञान नहीं है कि एबीआई कितने अच्छे हैं। मुझे कभी-कभी यह जानने की जरूरत है कि वे क्या हैं इसलिए मैं विधानसभा स्तर पर समझ सकता हूं / बहस कर सकता हूं।
माइकल बूर

1
एक अच्छा एबीआई कोड आकार और निर्देशों की संख्या को कम करता है, और मेमोरी के माध्यम से अतिरिक्त दौर की यात्राओं से बचकर निर्भरता श्रृंखला को कम विलंबता रखता है। (आर्गन्स के लिए, या स्थानीय लोगों के लिए जिन्हें स्पिल्ड / रीलोडेड करने की आवश्यकता है)। ट्रेडऑफ हैं। SysV के रेड-ज़ोन एक जगह (कर्नेल के सिग्नल-हैंडलर डिस्पैचर) में कुछ अतिरिक्त निर्देश लेते हैं, कुछ स्क्रैच स्पेस पाने के लिए स्टैक पॉइंटर को समायोजित नहीं करने के लिए पत्ती कार्यों के अपेक्षाकृत बड़े लाभ के लिए। तो यह लगभग शून्य के साथ एक स्पष्ट जीत है। SysV के लिए प्रस्तावित होने के बाद इसे बहुत अधिक चर्चा के साथ अपनाया गया था।
पीटर कॉर्डेस

1
@dgnuff: सही, यही कारण है कि कर्नेल कोड रेड जोन का उपयोग क्यों नहीं कर सकता । रुकावट कर्नेल स्टैक का उपयोग करती है, उपयोगकर्ता-अंतरिक्ष स्टैक का नहीं, भले ही वे सीपीयू उपयोगकर्ता-अंतरिक्ष कोड चला रहे हों। कर्नेल उपयोगकर्ता-स्पेस स्टैक पर भरोसा नहीं करता है क्योंकि उसी उपयोगकर्ता-स्पेस प्रक्रिया में एक और धागा इसे संशोधित कर सकता है, इस प्रकार कर्नेल का नियंत्रण ले सकता है!
पीटर कॉर्ड्स

1
@ DavidA.Gray: हाँ, ABI का कहना है कि आपको RBP को फ़्रेम पॉइंटर के रूप में उपयोग नहीं करना है, इसलिए अनुकूलित कोड आमतौर पर (उन कार्यों को छोड़कर allocaजो कुछ अन्य मामलों में उपयोग नहीं होते हैं)। यदि आप gcc -fomit-frame-pointerलिनक्स पर डिफ़ॉल्ट होने के लिए उपयोग किए जाते हैं तो यह सामान्य है । ABI स्टैक-लेड मेटाडेटा को परिभाषित करता है जो अभी भी काम करने के लिए अपवाद से निपटने की अनुमति देता है। (मुझे लगता है कि यह GNU / Linux x86-64 सिस्टम V के CFI सामान की तरह कुछ काम करता है .eh_frame)। gcc -fomit-frame-pointerx86-64 पर हमेशा के लिए डिफ़ॉल्ट (ऑप्टिमाइज़ेशन सक्षम होने के बाद) और अन्य कंपाइलर (जैसे MSVC) एक ही काम करते हैं।
पीटर कॉर्डेस

12

Win32 का ईएसआई और ईडीआई के लिए अपने स्वयं के उपयोग हैं, और आवश्यकता है कि उन्हें संशोधित नहीं किया जाए (या कम से कम यह कि उन्हें एपीआई में कॉल करने से पहले बहाल किया जाए)। मुझे लगता है कि 64-बिट कोड RSI और RDI के साथ ऐसा ही करता है, जो समझाता है कि वे फ़ंक्शन तर्कों को पास करने के लिए उपयोग क्यों नहीं किए जाते हैं।

मैं आपको यह नहीं बता सकता कि RCX और RDX को क्यों स्विच किया जाता है।


1
सभी कॉलिंग कन्वेंशनों में कुछ रजिस्टर खरोंच के रूप में नामित हैं और कुछ ईएसआई / ईडीआई और विन 64 पर आरएसआई / आरडीआई जैसे संरक्षित हैं। लेकिन वे सामान्य प्रयोजन रजिस्टर हैं, Microsoft उन्हें अलग तरीके से उपयोग करने के लिए समस्या के बिना चुना जा सकता था।
JanKanis

1
@ सोमजन: यकीन है, अगर वे पूरे एपीआई को फिर से लिखना चाहते थे और दो अलग-अलग ओएस थे। मैं उस "एक समस्या के बिना" नहीं कहूंगा, हालांकि। अब दर्जनों वर्षों से, MS ने x86 रजिस्टरों के साथ क्या होगा और क्या नहीं करेगा, इस बारे में कुछ वादे किए हैं, और वे कमोबेश सभी समय संगत और सुसंगत रहे हैं। वे सभी को खिड़की से बाहर फेंकने वाले नहीं हैं क्योंकि एएमडी से कुछ संपादन के कारण, विशेष रूप से एक मनमाना और "प्रोसेसर बनाने" के दायरे से बाहर।
cHao 16

5
@ सोमजन: AMD64 UN * X ABI हमेशा से यही था - एक UNIX- विशिष्ट टुकड़ा। दस्तावेज़, x86-64.org/documentation/abi.pdf , सिस्टम V एप्लिकेशन बाइनरी इंटरफ़ेस, AMD64 आर्किटेक्चर प्रोसेसर सप्लीमेंट शीर्षक के लिए एक कारण है। UNIX ABI ((एक बहु-मात्रा संग्रह, sco.com/developers/devspecs ) प्रोसेसर-विशिष्ट अध्याय 3 के लिए एक खंड छोड़ते हैं - पूरक - जो एक विशिष्ट प्रोसेसर के लिए फ़ंक्शन कॉलिंग कन्वेंशन और डेटा लेआउट नियम हैं।
फ्रैंक।

7
@Somejan: Microsoft Windows ने कभी भी UN * X के लिए विशेष रूप से पास होने का प्रयास नहीं किया है, और जब यह विंडोज़ को x64 / AMD64 में पोर्ट करने की बात आई, तो उन्होंने बस अपने स्वयं के __fastcall कॉलिंग सम्मेलन का विस्तार करने के लिए चुना । आप दावा करते हैं कि Win32 / Win64 संगत नहीं हैं, लेकिन फिर, बारीकी से देखें: एक फ़ंक्शन के लिए जो दो 32bit args लेता है और 32bit, Win64 और Win32 वापस लेता है , __fastcallवास्तव में 100% संगत हैं (दो 32bit args, समान रिटर्न मान पास करने के लिए regs)। यहां तक ​​कि कुछ बाइनरी (!) कोड दोनों ऑपरेटिंग मोड में काम कर सकते हैं। UNIX पक्ष पूरी तरह से "पुराने तरीकों" से टूट गया। अच्छे कारणों के लिए, लेकिन एक ब्रेक एक ब्रेक है।
फ्रैंक।

2
@ ऑलोफ: यह सिर्फ एक संकलक की तुलना में अधिक है। जब ईएएसआई और ईडीआई के साथ मेरे पास समस्या थी, जब मैंने एनएएसएम में स्टैनलोन सामान किया था। विंडोज निश्चित रूप से उन रजिस्टरों के बारे में परवाह करता है। लेकिन हाँ, यदि आप उन्हें करने से पहले उन्हें सहेजते हैं और विंडोज की आवश्यकता से पहले उन्हें पुनर्स्थापित करते हैं, तो आप उनका उपयोग कर सकते हैं।
cHao
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.