2012-07-01 13 views
6

मैं विभिन्न setjmp और longjmp कार्यान्वयन के स्रोत के माध्यम से ब्राउज़ कर रहा था और ध्यान दिया कि सभी CPU रजिस्ट्रार jmp_buf संरचना में सहेजे नहीं गए हैं। एएमडी 64 एबीआई की समीक्षा करने के बाद, मैंने देखा कि केवल कैली-सहेजे गए रजिस्टरों को ही सहेजा जाता है।setjmp (3) AMD64 पर सभी रजिस्टरों को क्यों नहीं बचाता है?

मुझे समझ में नहीं आता कि केवल कुछ रजिस्टरों को सहेजा गया है जब फ़ंक्शन स्थिति पूरी तरह से फिर से शुरू की जा सकती है। निश्चित रूप से जब तक मैं longjmp पर कॉल नहीं करता तब तक सहेजे गए रजिस्टरों को कई बार बार-बार गिरफ्तार किया जाना चाहिए था?

सब कुछ पूरी तरह से काम करता है, इसलिए निश्चित रूप से कुछ ऐसा है जो मुझे समझ में नहीं आता है। मैं उम्मीद कर रहा था कि कोई इस पर कुछ प्रकाश डाल सकता है।

धन्यवाद!

+0

setjmp के कार्यान्वयन हैं जो केवल निर्देश सूचक/फ्रेम सूचक को सहेजते हैं ('libunwind' देखें)। जिनके पास बहुत तेजी से सेटजंप है लेकिन अपेक्षाकृत धीमी लम्बी समय है और फ्रेम टेबल पर आधारित हैं जो वर्णन करते हैं कि अन्य रजिस्टरों को कॉलर से सहेजे गए स्थानों से कैसे पुनर्प्राप्त किया जाए। –

+0

मुझे वह स्रोत कहां मिल सकता है जिसे आप देख रहे थे? – nullpotent

+0

@AljoshaBre ये अब तक के सबसे अधिक पढ़ने योग्य हैं: [setjmp] (http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/setjmp /x86_64/setjmp.s;h=98f58b8d6551e391f426fc53c81678a03ac89074;hb=HEAD) और [longjmp] (http://git.etalabs.net/cgi-bin/gitweb.cgi?p=musl;a=blob;f=src/ setjmp/x86_64/longjmp.s; एच = e175a4b9606bba41eccc8972c22244e533718f0a; एचबी = HEAD)। – haste

उत्तर

4

setjmp फ़ंक्शन किसी अन्य की तरह एक फ़ंक्शन है, और इसलिए किसी भी कॉलर से सहेजे गए रजिस्टरों को पकड़ने के लिए माना जा सकता है। ऐसे में, उन रजिस्टरों को सहेजने/पुनर्स्थापित करने की आवश्यकता नहीं है।

+0

किसी भी उपलब्ध रजिस्टरों का उपयोग करने के लिए संकलक मुफ्त नहीं है क्योंकि यह मेरे कार्य के अंदर प्रसन्न होता है, i। ई। यहां तक ​​कि पंजीयक जो 'setjmp' द्वारा सहेजे नहीं जाते हैं? – haste

+0

पूरी तरह से नहीं - यह कॉलर सेव किए गए रजिस्टरों का उपयोग फ़ंक्शन कॉल में नहीं कर सकता है, क्योंकि वे बदल सकते हैं/बदल दिए जाएंगे। उदाहरण के लिए, 'eax' (x86 पर) पर विचार करें: कैली उस रजिस्टर में एक वापसी मूल्य लिखेंगे, इसलिए कॉलर फ़ंक्शन कॉल में कुछ भी महत्वपूर्ण स्टोर नहीं कर सकता है। – duskwuff

+1

@haste मैं इसके लिए भी गिर गया है। इसे थोड़ा और विस्तार से वर्णन करने के लिए: चूंकि वे कॉलर सेव किए गए हैं, और setjmp को सामान्य फ़ंक्शन के रूप में माना जाता है, सेटजैम्प का कॉलर पहले से ही उन रजिस्टरों को सहेजता है, इसलिए जब सेटजंप कॉलर को दूसरी बार लौटाता है (longjmp द्वारा) , कॉलर पहले संबंधित कॉलर से सहेजे गए रजिस्टरों को संग्रहीत करेगा और उन्हें पुनर्स्थापित करने में सक्षम होगा। –