खैर, dwarf2 हर कार्य के लिए टेबल, जिसमें यह शामिल हो क्या कॉल प्राप्त करने वाला बचाया रजिस्टर कर रहे हैं और जहां ढेर में वे सहेजे जाते हैं बनाता है, और जहां फ्रेम सूचक/callstack में वापसी पता है , और कुछ अन्य सामान। यदि आप बौने 2 का उपयोग करते हैं, तो कंपाइलर उन जानकारी का उपयोग कर सकता है और प्रभावी ढंग से रजिस्टरों को पुनर्स्थापित कर सकता है, और अपवाद की स्थिति में कॉलर्स पर वापस कूद सकता है। बैकएंड को उनके कार्यान्वयन के प्रस्तावना कोड में जानकारी प्रदान करने की आवश्यकता है, जीसीसी को बताने के लिए जो रजिस्ट्रार कैली-सेव हैं, और जब फ्रेम पॉइंटर बचाया गया था और ऐसी चीजें।
setjmp/longjmp का उपयोग करना सिर्फ एक हैक है। चूंकि setjmp/longjmp फ़ंक्शन फेंकने की संरचना के बारे में नहीं जानता है, इसलिए यह setjmp द्वारा जंप-बफर में सहेजे गए सभी रजिस्टरों को पुनर्स्थापित कर देगा, भले ही उन्हें फेंकने वाले फ़ंक्शन द्वारा ओवरराइड नहीं किया गया हो। मैं वास्तव में इसके लिए एक विशेषज्ञ नहीं हूं, लेकिन मुझे लगता है कि यह स्पष्ट है कि यह कुशल नहीं होगा। साथ ही, जब भी आप एक कोशिश ब्लॉक शुरू करते हैं, तो setjmp को सहेजे गए रजिस्टरों वाले बफर को सेट करने के लिए बुलाया जाना चाहिए, जबकि dwarf2 का उपयोग करते समय, संकलक संकलन समय पर पहले से ही सभी आवश्यक जानकारी प्रदान करता है।
यदि बैकएंड आवश्यक जानकारी प्रदान नहीं करते हैं, तो जीसीसी स्वचालित रूप से setjmp/longjmp आधारित अपवाद हैंडलिंग पर वापस आ जाएगी।
नोट मैं एक जीसीसी विशेषज्ञ नहीं हूं। मैंने बस जीसीसी सहित मेरे प्रोफेसर के कुछ आसान प्रोसेसर को टूलचैन पोर्ट किया। मुझे आशा है कि मैं आपकी मदद कर सकता हूं।
स्रोत
2008-11-25 18:46:20
ध्यान दें कि http://www.nongnu.org/libunwind/ मौजूद है, जिसमें एक कुशल 'setjmp' कार्यान्वयन है जो स्वयं बौने तालिकाओं पर आधारित है। तो 'setjmp' तो बस स्टैकपोइंटर को स्टोर करने की आवश्यकता है और बाकी को पहले से ही काम कर रहे बौने अवांछित को छोड़ दें। –