2015-04-17 30 views
96

Meslektaşımdan, main() işlevini yazmadan bir C programını yazıp çalıştırabileceğini öğrendim. BuC dilinde _start() kullanımı nedir?

// Compile it with gcc -nostartfiles 

void _start() { 
    int ret = my_main(); 
    exit(ret); 
} 

int my_main() { 
    puts("This is a program without main!\n"); 
    return 0; 
} 

olarak derleme withoutMain.c

altında olarak yapılabilir: gcc -o withoutMain withoutMain.c –nostartfiles

Run o kadar: Biri gerekir zaman ./ withoutMain

Benim sorum Bu tür bir şey yapmak? Bazı gerçek dünya senaryosu? main iken

+1

Uzaktan ilgili: http://stackoverflow.com/questions/2548486/compiling-without-libc –

+6

Programların nasıl başlatıldığının bazı iç çalışmalarını gösteren klasik makale: [Gerçekten Teensy ELF Executables oluşturma konusunda bir kasırga öğreticisi Linux] (http://www.muppetlabs.com/~breadbox/software/tiny/teensy.html). Bu, _start() 'ın bazı daha ince noktalarını ve 'main()' dışındaki diğer şeyleri tartışan iyi bir okumadır. –

+0

C dili kendisi _start' 'hakkında hiçbir şey söylemez ya' main' dışında herhangi bir giriş noktası hakkında (giriş noktasının adı Uygulama tanımlı (embedded) uygulamalarını ayaklı için olduğunu hariç). –

cevap

78

_start sembolü, programınızın giriş noktası giriş noktasıdır. Yani, o sembolün adresi, program başlangıcında atlanan adrestir. Normal olarak, _start adıyla işlev, C çalışma ortamı ortamının başlangıç ​​kodunu içeren crt0.o adlı bir dosya tarafından sağlanır. Bazı şeyleri ayarlar, argüman dizisini argv doldurur, kaç argümanın bulunduğunu sayar ve sonra main'u çağırır. main döndükten sonra, exit çağrılır.

Bir program C çalışma zamanı ortamını kullanmak istemiyorsa, kendi kodu _start için sağlaması gerekir. Örneğin, Go programlama dilinin referans uygulaması öyle yapar ki, yığınla biraz sihir gerektiren standart olmayan bir diş çekme modeline ihtiyaçları vardır. Alışılmadık şeyler yapan programlar veya programlar yazmak istediğinizde kendi _start ürününü tedarik etmek de yararlıdır.

+2

Bir başka örnek de Linux'un kendi _start tanımına sahip dinamik bağlayıcı/yükleyicisidir. –

+2

@BlueMoon Ancak bu 'start ', crt0.o' nesnesinden de geliyor. – fuz

+0

Bu davranış dil standardında mı? Birçok gömülü sistem derleyicisiyle (Linux kullanmayan) kullanıldığını gördüm. –

35

bir programcı perspektifinden programınız için giriş noktasıdır, _start OS perspektifinden bir de (program OS başlatılmasından sonra yürütülür ilk öğretim)

her zamanki giriş noktasıdır Tipik C ve özellikle C++ programı, yürütme ana girmeden önce çok fazla çalışma yapılmıştır. Özellikle küresel değişkenlerin başlatılması gibi şeyler. Here_start() ve main() arasında devam eden her şeyin iyi bir açıklamasını ve aynı zamanda ana çıkıştan sonra da (aşağıdaki resme bakın) bulabilirsiniz.
Bunun için gerekli kod genellikle bir başlangıç ​​dosyasındaki derleyici yazıcılar tarafından sağlanır, ancak –nostartfiles bayrağındaki ile aslında derleyiciye şunları söylersiniz: "Bana standart başlatma dosyasını eklemekten rahatsız ol, neler olup bittiğini kontrol et başlangıçtan sağa".

Bu bazen gerekli ve sıklıkla gömülü sistemlerde kullanılır. Örneğin. Eğer bir işletim sisteminiz yoksa ve global sisteminizin başlatılmasından önce bellek sisteminizin belirli bölümlerini (örneğin, önbellekleri) manuel olarak etkinleştirmeniz gerekir.

+0

Genel değişkenler, veri bölümünün bir parçasıdır ve bu nedenle, programın yüklenmesi sırasında kurulurlar (eğer bunlar metin bölümü, aynı öyküdürler ise). _start işlevi bununla tamamen ilgisiz. – Cheiron

+0

@Cheiron: Üzgünüm, C++ içinde benim emistake, küresel değişkenler genellikle _start 'iç çalıştırılan bir kurucu()' (ya aslında tarafından çağrılan başka fonksiyonu) tarafından ve birçok Bare-Metal-Programlar başlatılır, açıkça bütün kopyalamak flash'dan RAM'a ilk global veri, ki bu da '_start()' da olur, fakat bu soru ne C++ ne de çıplak-metal koduyla ilgili değildi. o kuyudan herhangi uyumsuz olmayan-sinyal güvenli işlevini kullanmak güvensiz olabilir - Eğer kendiniz yapmak için özel adımlar atmamaları halinde kendi '_start' besleyen bir programda, C kütüphanesi başlatıldı almazsınız o – MikeMB

+1

Not Böyle bir program. (Herhangi bir * kütüphane işlevi çalışacak * Resmi bir garanti yok, ama zaman uyumsuz-sinyal güvenli işlevler hiç bir küresel verilere başvuruda bulunamaz, bu yüzden arızaya kendi yolumdan gitmek gerekir.) – zwol