2011-01-04 6 views
4

von einem der Programmierung Bücher Unix Zitiert,Was ist für eine C-Startroutine erforderlich?

Wenn ein C-Programm durch die kernelby ausgeführt wird, eine der exec-Funktionen spezielle start-up routine nennt. Diese Funktion wird aufgerufen, bevor die Hauptfunktion aufgerufen wird. Die ausführbare Programmdatei gibt diese Routine als die Startadresse für das Programm an; Dies wird vom Linkeditor eingerichtet, wenn es vom C-Compiler aufgerufen wird. Diese Start-up-Routine nimmt Werte aus dem Kernel die Kommandozeilenargumente und die Umgebung und richtet Dinge so , dass die Hauptfunktion als früher gezeigt aufgerufen wird.

Warum brauchen wir einen mittleren Mann start-up routine. Die exec-Funktion könnte direkt die Hauptfunktion genannt haben und der Kernel hätte die Befehlszeilenargumente und die Umgebung direkt an die Hauptfunktion übergeben können. Warum brauchen wir dazwischen die Startup-Routine?

+0

Sicherlich "brauchen" Sie es nicht, es ist nur eine Annehmlichkeit. –

+0

Können Sie mir bitte sagen, welche Bequemlichkeit bietet es? –

Antwort

9

Weil C hat kein Konzept von "Plug-in". Wenn Sie also sagen wollen, malloc() muss jemand die notwendigen Datenstrukturen initialisieren. Die C-Programmierer waren faul und wollte nicht, Code zu schreiben haben, wie dies die ganze Zeit:

main() { 
    initialize_malloc(); 
    initialize_stdio(); 
    initialize_...(); 
    initialize_...(); 
    initialize_...(); 
    initialize_...(); 
    initialize_...(); 

    ... oh wow, can we start already? ... 
} 

So der C-Compiler herausfindet, was getan werden muss, erzeugt den notwendigen Code und setzt alles auf, so dass Sie kann sofort mit Ihren Code beginnen.

+0

Perfekt ... Vielen Dank :) –

5

Die Start-Routine initialisiert die CRT (d. H. Erzeugt den CRT-Heap, so dass malloc/free funktioniert, initialisiert Standard-I/O-Ströme usw.); im Fall von C++ ruft es auch die Konstruktoren der Globals auf. Es kann andere systemspezifische Einstellungen geben, Sie sollten die Quellen Ihrer Laufzeitbibliothek für weitere Details überprüfen.

4

Aufruf main() ist eine C-Sache, während der Aufruf _start() ist eine Kernel-Sache, durch den Einstiegspunkt im Binärformat-Header angezeigt. (Zur Klarheit: der Kernel will oder muss nicht wissen, dass wir es _start nennen)

Wenn Sie eine Nicht-C-Binärdatei haben, haben Sie möglicherweise keine main() Funktion, die Sie möglicherweise nicht einmal das Konzept haben eine "Funktion" überhaupt.

Also die eigentliche Frage wäre: Warum gibt ein Compiler nicht die Adresse main() als Ausgangspunkt? Das liegt daran, dass typische libc-Implementierungen einige Initialisierungen durchführen müssen, bevor sie das Programm wirklich starten, siehe die anderen Antworten dazu.

bearbeiten als Beispiel, können Sie den Einstiegspunkt wie folgt ändern:

$ cat entrypoint.c 
int blabla() { printf("Yes it works!\n"); exit(0); } 
int main() { printf("not called\n"); } 

$ gcc entrypoint.c -e blabla 

$ ./a.out 
Yes it works! 
+0

Ausgezeichnet. Ich werde mehr erfahren. Vielen Dank :) –

+0

@LinuxPenseur: auch sehen und probieren Sie das Beispiel, das ich gerade hinzugefügt habe! ohne den 'exit (0)' wird es SIGSEGV, könntest du schon erklären, warum das passieren würde? – mvds

0

Wichtig zu wissen ist auch, dass ein Anwendungsprogramm im User-Modus ausgeführt wird, und jedes System ruft, stellen die privilegiertes Bit und gehen in den Kernel-Modus. Dies trägt zur Erhöhung der Sicherheit des Betriebssystems bei, indem verhindert wird, dass der Benutzer auf Systemaufrufe auf Kernel-Ebene zugreifen kann, und eine Vielzahl anderer Komplikationen. So wird ein Aufruf von printf abfangen, Kernelmodus-Bit setzen, Code ausführen, dann auf Benutzermodus zurücksetzen und zu Ihrer Anwendung zurückkehren.

Der CRT wird benötigt, um Ihnen zu helfen und Ihnen zu ermöglichen, die gewünschten Sprachen in Windows und Linux zu verwenden. Es bietet ein sehr grundlegendes Bootstrapping in das Betriebssystem, um Ihnen Funktionen für die Entwicklung zur Verfügung zu stellen.