¿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.