PDA

View Full Version : entry point در برنامه های سیستمی



barnamenevis300
دوشنبه 22 خرداد 1391, 16:14 عصر
برای درک بهتر نحوه کامپایل شدن پروژهای نرم افزاری سیستمی میخوام بدونم اولین فایل سورس و اولین تابعی که مثلا در سورس کرنل لینوکس وجود داره چیه؟ مثلا در نرم افزار های معمولی main یا winmain هست ولی در سیستمی ها کامپایل با چه معیاری صورت میگیره؟

pswin.pooya
سه شنبه 23 خرداد 1391, 00:30 صبح
عنوان تاپيك رو درست نوشتي و متنش رو اشتباه.

توي تمام برنامه ها يه نقطه ورود وجود داره كه توسط لينكر مشخص ميشه. براي برنامه هاي سي بطور پيش فرض نقظه ورود تابع main رو صدا ميزنه. اما اين قضيه مي تونه متفاوت باشه. يعني حتي برنامه ميتونه تابع main نداشته باشه و با يه تابع مثل foo و يا هر تابع ديگه شروع بكار كنه.

داخل سيستم عامل هم دقيقا به همين شكل هست بوت لودر نقطه ورود هسته رو مي خونه و اجراش ميكنه بعدش نقطه ورود كه عمدتا يك تابع C ( با هر نامي مثل kmain هست) صدا زده ميشه. اين نقطه ورود معمولا ( يعني تقريبا هميشه) يك كد اسمبلي است كه داخل x86 با دستور call تابع main رو صدا ميزنه.

متاسفانه اكثر كتابهاي برنامه نويسي زبانهاي C و C++ داراي اشتباهات بزرگي هستن كه از جمله اونها ميشه به موارد زير اشاره كرد:


برنامه ها حتما بايد تابع main داشته باشن => دليلي براي وجود main نيست.
نقطه ورود برنامه ها main است. => بازم دليلي نداره.
new و delete كلمه كليدي هستند => نه خير اين دو عملگر هستند نه كلمه كليدي. فرق عملگر با كلمه كليدي اينه كه عموما ميشه براي عملگر يك رفتار جديد تعريف كرد و معمولا عملگرها تابع هستند. مثلا شما براي كلمه كليدي if نمي تونيد رفتار جديد تعريف كنيد اما مي تونيد براي delete اينكار رو انجام بديد
كتابها معمولا تعريفي براي C Runtime ارائه نمي دن.
معمولا STL رو جدا از C++ مي دونند => C++ از سه قسمت CRT، سينتكس C++ و كتابخونهاي STL تشكيل شده. فرق سينتكس با بقيه اينه كه شما مختاريد كه داخل CRT و STL دست ببريد و يا اونها رو حذف كنيد.

البته كاستي هاي زياد ديگه اي هم داخل كتابها مشاهده ميشه كه متاسفانه منبع اونها نوسنده هاي كم تجربه و اساتيد بي سواد دانشگاهي هستند. كشورهاي خارجي قالبا با نويسنده هاي كم تجربه در كتابها رو به رو هستند چون افراد با تجربه كه شامل استايد هم ميشه قالبا بجاي كتاب سراغ مستندات ميرن. و اين مورد داخل دانشگاها توسط اساتيد برطرف ميشه. اما داخل كشور عزيزمون معمولا اساتيد محترم ، معضل بسيار بزرگتري از كتابها هستند چون اطلاعات غلط رو به جامع دون تجربه دانشجوها تزريق مي كنند و اونها هم به همين شكل به بقيه و اين روند ادامه پيدا ميكنه. من خودم توي دوران ليسانس حدود 2 بار سر اين قضيه بشدت با اساتيدم درگير شدم.

barnamenevis300
چهارشنبه 24 خرداد 1391, 00:34 صبح
در آخر حرف های دل من رو زدید. اینکه برنامه های سی نقطه ورود رو main قرار میده رو میخوام بهتر درک کنم برای همین اجازه بدید اینگونه بپرسم: ببینید معمولا برنامه های سی در چند تا فایل مجزا نوشته میشن حالا آیا تصور من درسته که فایل پیش فرص که entry point در اون هست فایلی هست که "هم نام " با تابع entry point هست؟ مثلا فایل main.c که در اون تابع main () هست. و اینکه فایل های دیگر به چه صورت مورد رفتار قرار می گیرند (این سوال رو میپرسم چون بنده برنامه نویسی معمولی رو هم تجربه عملی ندارم، در واقع با نحوه کامپایل چند فایل مجزا آشنا نیستم) آیا تصور من درسته که فایل های ذیگه در انتهای برنامه با فایل اصلی گنجاده شده فرض میشن؟
نمی دونم منظور من رو به طور کلی میفهمید یا نه که میخام چی بپرسم! شاید روزی خود شما هم این گونه سوالات عجیب می پرسیدید.

pswin.pooya
چهارشنبه 24 خرداد 1391, 02:18 صبح
نمی دونم منظور من رو به طور کلی میفهمید یا نه که میخام چی بپرسم! شاید روزی خود شما هم این گونه سوالات عجیب می پرسیدید.
خب راستش بخواي خوب ميفهمم و مدت زيادي توي ذهن من هم سوال بود.

شما هر وقت تابعي مي نويسيد نام اون تابع به صورت يك نشانه (symbol) داخل جدول نشانه نگهداري ميشه. اين جدول شامل نامها و آدرس اونها هست. پس هر جا كه لازم باشه مثلا تابع foo صدا زده بشه لينكر آدرس اون تابع بر ميداره و بجاي نام ميذاره. حالا اسم فايل هرچي ميخواد باشه و يا پروژه هر چند تا فايل كه ميخواد داشته باشه مهم نيست. چون لينكر در آخر كار زمان ساختن از نام توابع و متغييرها استفاده ميكنه.

كد زير نقطه ورود هسته سيستم عامل من هست:
http://arax.svn.sourceforge.net/viewvc/arax/arch/x86/init/entry.s?revision=17&view=markup

اگر دقت كني خط زير رو ميبيني:

call kmain ; call our main() function

من توي اين خط گفتم كه تابع kmain صدا زده بشه. حالا براي من مهم نيست كه kmain كجا تعريف شده باشه بلكه اين وظيفه لينكر هست كه بره اون رو پيدا كنه و عبارت kmain رو با آدرس جايگزين كنه.

اين مباحث مربوط به درس كامپايلر و طراحي زبانهاي برنامه نويسي هست كه براي كامپايلر بهترين مرجع كتاب اهو است. ( از نظر تئوريك)

متاسفانه مايكروسافت چون فرايند لينك و كامپايل رو از برنامه نويسها مخفي ميكنه. اين قضيه براي خيلي از برنامه نويسها سوال ميشه. و باعث ايجاد ضعفهاي برنامه نويسي ميشه. برنامه نويسهاي حرفه اي كه بعد از يه مدت با لينوكس درگير ميشن و چون اونجا اين تفاوتها رو حس ميكنن و همه چي براشون شفاف ميشه. با لنوكس حسابي حال ميكنن و به همين دلايل به لينوكس ميگن بهشت برنامه نويسها چون همه چي رو به معناي تمام ميتوني كنترل كني.

barnamenevis300
چهارشنبه 24 خرداد 1391, 03:39 صبح
فرق پسوند .S با .asm چیه؟ و چرا برای نقطه شروع همیشه از این پسوند استفاده میشه؟

pswin.pooya
چهارشنبه 24 خرداد 1391, 11:38 صبح
فرق پسوند .S با .asm چیه؟
هيچي. فقط يه پسوند هست. توي لينوكس رسم هست كه از .s براي اسمبلي استفاده كنن.

barnamenevis300
چهارشنبه 24 خرداد 1391, 14:10 عصر
یه سوالی می پرسم می ترسم فک کنید بی ربطه ولی از نظر خودم ربط داره... من مثلا یکی از این فایل ها رو در لینوکس میخوام کامپایل کنم با gcc حالا نمیدانم در خط فرمان لینوکس پوشه پیش فرض چیه؟ یعنی اون فایل که قراره کامپایل بشه رو باید در چه فولدری از لینوکس کپی کنم که فولدر پیش فرضه و بعد با دستور gcc کامپایلش کنم؟