ओएस लिखने के प्रयास में, मुझे कार्य स्विचिंग के लिए वर्तमान फ़ंक्शन के अंत (एपिलॉग से ठीक पहले) का पता प्राप्त करने की आवश्यकता है।
कंक्रीटली मेरी समस्या है कि ईआईपी को कॉपी किए गए स्टैक के अंदर मेरे नव निर्मित कार्य (प्रक्रिया) को असाइन करना है। मैं पहले से ही एक प्रक्रिया के लिए रजिस्टरों को सहेजने/पुनर्स्थापित करने में कामयाब रहा हूं, लेकिन मुझे यह पता लगाना होगा कि बच्चे की प्रक्रिया में ईआईपी में क्या मूल्य होगा।जीसीसी - लेबल पता वास्तविक लेबल पते के बजाय वर्तमान ईआईपी लौटाता है
मैं सी मानक के जीसीसी के एक्सटेंशन का इस्तेमाल किया: Labels as Values और Local Labels
प्रलेखन से: आप एकल ऑपरेटर '& &' के साथ एक लेबल वर्तमान समारोह में परिभाषित के पते (या एक से युक्त समारोह) मिल सकता है। मान प्रकार शून्य है *।
और: जीसीसी आपको किसी भी नेस्टेड ब्लॉक स्कोप में स्थानीय लेबल घोषित करने की अनुमति देता है। एक स्थानीय लेबल एक साधारण लेबल की तरह है, लेकिन आप इसे केवल उस ब्लॉक के भीतर संदर्भित कर सकते हैं (एक गोटो स्टेटमेंट के साथ, या अपना पता ले कर) जिसमें इसे घोषित किया गया है।
pid_t fork(void)
{
__label__ fork_end;
...
task->regs.eip = (uintptr_t)&&fork_end;
...
return task->pid;
fork_end:;
}
जीसीसी यह संकलन, बस अमानक कोड के बारे में चेतावनी के साथ करता है।
लेकिन जब disassembled, gdb पता चलता है:
task->regs.eip = (uintptr_t)&&fork_end;
0x00105008 <+87>: mov $0x105008,%edx
0x0010500d <+92>: mov -0xc(%ebp),%eax
0x00105010 <+95>: mov %edx,0x40(%eax)
...
fork_end:;
}
0x00105096 <+229>: leave
0x00105097 <+230>: ret
मैं उम्मीद task->regs.eip = (uintptr_t)&&fork_endl
0x00105096
बजाय 0x00105008
को बचाने के लिए।
CFLAGS
-O0 -std=gnu99 -fgnu89-inline -DDEBUG -ggdb3 -ffreestanding -fbuiltin
हैं (चेतावनियां संबंधित विकल्प यहां नहीं दिखाए गए हैं)।
__label__ fork_end;
टिप्पणी कुछ भी नहीं बदलता है।
कृपया '&&' के बारे में जीसीसी दस्तावेज का संदर्भ प्रदान करें और बताएं कि यह आपकी समझ में क्या करता है। एक्सटेंशन का उपयोग करते समय यह चेतावनी नहीं देता है। [पूछें] देखें और सभी आवश्यक जानकारी प्रदान करें। – Olaf
संपादित, और @ ओलाफ, जीसीसी ने '-Wpedantic' विकल्प के साथ गैर-मानक कोड के बारे में चेतावनी दी है। आपकी सलाह के लिए धन्यवाद। – Aerath
आह, मैं देखता हूं। एक्सटेंशन के साथ '-Wpedantic' का उपयोग करना एक बुरा विचार की तरह ध्वनि। वैसे भी, आपकी कास्ट कार्यान्वयन को परिभाषित किया गया है और एक 'uint32_t' को पॉइंटर रखने के लिए तैयार नहीं किया गया है, न ही 1: 1 असाइनमेंट है। 64 बिट सिस्टम पर आप पहले ही बस्टेड हैं। कम से कम सही प्रकार का प्रयोग करें। किसी भी कारण से आप एक सूचक के रूप में 'शून्य *' का उपयोग नहीं करते हैं, लेकिन एक पूर्णांक? – Olaf