Tam Sürümünü Görmek İçin : main() fonksiyonunu kim çağırır?
Başlıkta yazdığım gibi main() fonksiyonunu kim çağırır? İşletim sistemi mi, programın kendisi mi, program loaderler mı, derleyici mi?
Bu konuda seviyeli ve yeni fikirleri olan arkdaşlara şimdiden teşekkür ediyorum.
http://en.wikibooks.org/wiki/C_Programming/Q&A
main fonksiyonunu işletim sistemi çağırırmış.
http://www.csystem.org/display_source.php?id=104&keyword=&subject=23
Linke bakarmısın.
"Obfuscated C" yarışmasından alınmıştır. Bu yarışma kodu en anlaşılmaz ve derleyicinin en standart dışı kullanımını hedefliyor. Ve main() kendimi defalarca kendi çağırmış. İşletim sistemi çağırmış olsaydı defalarca program bitip yeniden başlamış gibi olur du ama olmadı.
Ben sizin kişsel görüşlerini almak istedim.
Kişisel not: wikipedia resmi bir oluşum değil ve oradaki bilgilerin resmi değeri yok.
Her kodun başlangıç noktası var main fonksiyonuda C /C ++ için başlangıç noktasını gösterir ve işletim sistemi oradan çalıştırmaya başlar
C / C++ da fonksiyonlar kendi kendini çağırabilir main de bir fonksiyondur
pek normal bir kullanım olmasada mümkün
sonuç main fonksiyonu programı başlatmak için işletim sistemi tarafından en başta çalıştırılır. sonrası senin yazdığın koda göre çalışır
#include <iostream>
using namespace std;
int main(){
cout<<"me here"<<endl;
system("pause");
return main();
}
bu kod da çağırıyor.
fakat ilk çağrıyı kim nasıl yapıyor, tam Euclides lik soru :)
Teşekkürler bu bir bilgi yarışması değil. Kimse kimsenin bilgisini ölçmeye çalışmıyor. Böyle bir haddi de yok. Sizin yaklaşımınız çok güzel ben de bunu istiyordum. Fikirlerinizi almak. Sizin bahsettiğiniz startup kodu dediğimiz kısım bu da main i çağırıyor galiba. Bu durumda işletim sistemi ve programın kendisi iyi aday olarak duruyorlar. Birinde karar kılabilceğiz galiba.
İlginiz için teşekkürler.
mr1yh1 evet birkaç dilde daha oluyor. reküsif/ özyinelemeli fonksiyonları biliyoruz hepimiz. Verdiğim örnek çok eski bir program ama bu ilginç duruma uygundu. winmain() fonksiyonun da da oluyor. :)
myavuzselim
28/12/2006, 17:01
Burada linux icin anlatilmis: http://linuxgazette.net/issue84/hawk.html
Kisaca "Summing up" bolumune bakabilirsiniz.
On Linux, our C main() function is executed by the cooperative work of GCC, libc and Linux's binary loader.
Conclusion
On Linux, our C main() function is executed by the cooperative work of GCC, libc and Linux's binary loader.
Bu da başladığımız yere döndürdü hepsi beraber diyor. :)
link için teşekkürler. Peki windows için?
Bu durum biraz derleyici bağımlı olsa da, özetle şu şekilde olur.
Her derleyici hazırladığı exe için bir run time library kodu gömer exenin içine.C için konuşacak olursak CRT ( C Run-Time).
Program çalışmaya burdan itibaren başlar.CRT startup kodu CRT libraryi yükler, global değişkenler ve static değişkenler için yapılandırıcıları çağırır.Çünkü bunlar main'den önce hazır olmalı.En son olarak da main fonksiyonunu çağırır.
Yani main()'i çağıran ilk elden crt startup code'dur.
Not:Bilgisayarınızda crt0.c dosyasını aratırsanız daha detaylı bilgiye ulaşabilirsiniz düşülen açıklamalardan...
Aşağı yukarı ben de sizinle aynı fikirdeyim winmain() ile bu iş daha güzel açıklanıyor. Eski kodlarımın arasında assembly kodları var bu konuyla ilgili bulup eklerim, program kendi çağırıyor gibi yani ama net bişey söylememek lazım.
Askerdeydim bensiz zorlanmıssınız :D ozlememişinizdir sanırım beni.. ASM programcıları sevmez bu ağlem :D 1,5 senede ismimi anan olmamış ..
heyse konuyu anlatayım..
şimdi oncelikle sunu aklımızda tutalım... İki cesit calısan kod var..
başlık dosyası olmayanlar: Mesela Bin Com BIOS dosyalar. Bunlar yüklendikleri yerden calısır...
başlık dosyalılar... NZ,MZ,PE, Linnux_Runbaşlıklı dosyalar için PE yi inceleyelim.. Windowsta bir pe calıstırmak istediğinizde siz dosyaya tıkladığınız zaman. Load windows prosesleri uygulanır. Dosya uzantısı exe olduğu icin dosya bir miktar bellekte acılır ilk kısımdaki Dos headerdan sonraki PE header için PE imzasına bakılır ve calışabilir dosya olduğu anlaşılır.
Pe'de belirtilen sectionların acılması için sanal bellek yaratılır ve tüm sectionlar pede belirtilen bellek noktalarına acilir. Yüklenecek dllleri belirten section tablodan bulunur bahsi gecen Dlller için bir isimlerin tablosu olusturulur bu tabloya Dlller yüklenir ve Call pointerleri yazılır.
PE için code section'da calisacak kod noktasi bulunmaktadir EIP değeri o değere getirilir ve program şler..
İlk verilen EIP komutları bir dizi kodu işletir. Bu kodu derleyici olusturur ve yaklasık olarak soyle bişidir.
push 0
call GetModuleHandle
mov hInstance,eax
call GetCommandLine
mov CommandLine,eax
push SW_SHOWDEFAULT
push CommandLine
push 0
push hInstance
call Procedure
push eax
call ExitProcess
Procedürler için cağrılan cağrı genellikle command line girdisini okuyup bir diziye ceviren bir algoritmadın ve Main için bu fonksiyonun girdilerini düzenler ve değerleri PUSH eder.en sonunda bu cağrı sizin yazdığınız main fonksiyon için call main prosedürünü yapar bolece main ile belirli adrese cağrı yapmış olursunuz..
yani kısaca:
işletim sistemi başlık dosyasına göre calisir programi belleğe yükler ve başlik dosyasında belirtilen noktadan dosyanın calimasını sağlar.
başlık dosyasında belirtilen noktada komut satırı gibi bilgilerin düzenlenip push edildiği derleyicinin yazdığı ozel bir kod bulunur. (hatta derleyicinin ne olduğu bazen bu koddan anlasılır, bir tür imzadır)
calısan bu kod main olarak yazdığınız derlenmiş kodun adresine call ile cağrı yapar..
Sonucta main fonksiyona en son cağrıyı yazdığınız kodu derleyen derleyicinin yazdığı bir kod bloğu yapmaktadır.. Bu kodun calişması için de işletim sistemi başlığa göre dosyayı yükler...
Forum Yazılımı : vBulletin v3.6.8, Copyright ©2000-2008, Jelsoft Enterprises Ltd.