c unix

¿Para qué sirve_start() en C?



unix (3)

Aprendí de mi colega que uno puede escribir y ejecutar un programa en C sin escribir una función main() . Se puede hacer así:

my_main.c

/* Compile this with gcc -nostartfiles */ #include <stdlib.h> void _start() { int ret = my_main(); exit(ret); } int my_main() { puts("This is a program without a main() function!"); return 0; }

Compílalo con este comando:

gcc -o my_main my_main.c –nostartfiles

Ejecútalo con este comando:

./my_main

¿Cuándo se necesitaría hacer este tipo de cosas? ¿Hay algún escenario del mundo real en el que esto sea útil?


El símbolo _start es el punto de entrada de su programa. Es decir, la dirección de ese símbolo es la dirección saltada al inicio del programa. Normalmente, la función con el nombre _start es suministrada por un archivo llamado crt0.o que contiene el código de inicio para el entorno de tiempo de ejecución C. Configura algunas cosas, llena la matriz de argumentos argv , cuenta cuántos argumentos hay y luego llama a main . Después de los retornos main , se llama a exit .

Si un programa no quiere usar el entorno de tiempo de ejecución C, debe proporcionar su propio código para _start . Por ejemplo, la implementación de referencia del lenguaje de programación Go lo hace porque necesitan un modelo de subprocesamiento no estándar que requiere algo de magia con la pila. También es útil proporcionar su propio _start cuando desea escribir programas realmente pequeños o programas que hacen cosas poco convencionales.


Si bien main es el punto de entrada para su programa desde la perspectiva de los programadores, _start es el punto de entrada habitual desde la perspectiva del sistema operativo (la primera instrucción que se ejecuta después de que su programa se inició desde el sistema operativo)

En un programa típico de C y especialmente de C ++, se ha realizado mucho trabajo antes de que la ejecución entre en main. Especialmente cosas como la inicialización de variables globales. Here puede encontrar una buena explicación de todo lo que sucede entre _start() y main() y también después de que main haya salido nuevamente (vea el comentario a continuación).
El código necesario para eso generalmente lo proporcionan los escritores del compilador en un archivo de inicio, pero con el indicador –nostartfiles esencialmente le dice al compilador: "No te molestes en darme el archivo de inicio estándar, dame control total sobre lo que está sucediendo correctamente desde el comienzo".

Esto a veces es necesario y a menudo se usa en sistemas integrados. Por ejemplo, si no tiene un sistema operativo y tiene que habilitar manualmente ciertas partes de su sistema de memoria (por ejemplo, cachés) antes de la inicialización de sus objetos globales.


_start() es una función que apunta el encabezado especial, para que la computadora la entienda. Pero es importante porque debemos aprender lo que sucederá en la parte posterior de la computadora.