¿Qué sucede antes de main ()?

3

Estoy trabajando en sistemas integrados como principiante y he encontrado archivos como start.s o cstart que se ejecutan antes de que comience la función main (). ¿Cuál es el propósito de estos o archivos similares? ¿Qué información le estamos diciendo al sistema? He oído hablar de la inicialización, pero no sé exactamente qué es eso.

    
pregunta Mediocre

4 respuestas

4

Es completamente dependiente del compilador y la arquitectura, pero generalmente ese código inicializa el hardware más básico requerido para que se ejecute el resto del código. El código por ejemplo:

  • Define los vectores de reinicio

  • Define el diseño de los datos en la memoria (muchos sistemas usan un script de enlace en su lugar)

  • Define las direcciones de las rutinas de servicio de interrupción en una tabla grande (la tabla de vectores de interrupción)

  • Inicializa los registros de la CPU, por ejemplo, el puntero de pila

  • Configura el reloj central

Además, esa sección también satisface las necesidades de tiempo de ejecución del lenguaje de programación utilizado. Es:

  • Inicializa cualquier función que utilice el sistema de paso de parámetros

  • Inicializa las variables globales por ejemplo. copiando contenidos flash a la memoria RAM y inicializando a cero

  • Si se usa la asignación de memoria dinámica, inicializa el montón

  • Si la matemática de punto flotante está habilitada, inicializa la FPU (si está disponible) o inicializa la biblioteca de punto flotante

  • Si se usan excepciones, inicializa el manejo de excepciones.

respondido por el jms
2

Pregunta un tanto relacionada: ¿Quién recibe el valor devuelto por main ()?

main() es una función ordinaria de C, por lo que requiere que ciertas cosas se inicialicen antes de que se llame. Estos están relacionados con:

  • Configuración de una pila válida
  • Crear una lista de argumentos válida (normalmente en la pila)
  • Inicializando el hardware de manejo de interrupciones
  • Inicializando variables globales y estáticas (incluido el código de la biblioteca)

El último elemento incluye elementos tales como configurar una agrupación de memoria que pueden usar malloc() y free() , si su entorno admite la asignación de memoria dinámica. De manera similar, cualquier forma de "E / S estándar" a la que su sistema pueda tener acceso también se inicializará.

Casi todo lo demás dependerá de la aplicación, y tendrá que inicializarse desde dentro main() , antes de ingresar su "bucle principal".

    
respondido por el Dave Tweed
2

En un sistema embebido típico, el código de inicio como mínimo tendrá que cargar todas las variables inicializadas con sus valores definidos y poner a cero todos Variables no inicializadas. Dependiendo de la plataforma de hardware, puede También tiene que configurar el puntero de pila de CPU [en algunas plataformas de hardware, un reiniciará automáticamente el puntero de pila en la parte superior de la memoria, pero en otras plataformas debe configurarse manualmente] o configurar otras características en la CPU o controlador de memoria.

El código de inicio suele ser bastante corto y simple, y algunas plataformas pueden documente cómo funciona y permita a un usuario sustituir otra cosa (por ejemplo, si un sistema integrado deberá tener una copia de rutina de inicio provista por el usuario Algún código de un chip flash de serie en la RAM y luego ejecutarlo, puede hacer que tiene sentido tener variables inicializadas que sean parte de la imagen del código, en lugar de teniendo sus valores iniciales formando parte de la imagen de código que se copia a otra área de RAM en el inicio, pero luego se ignora).

    
respondido por el supercat
1

En una cadena de herramientas de escritorio GNU / Linux tradicional, la mayor parte de dicho código está implementado por glibc y está contenido en objetos como crti.o , puede obtener la lista completa con gcc --verbose main.c .

Básicamente, glibc, está configurando las cosas para que más llamadas de glibc funcionen correctamente.

Por lo tanto, puedes aprender lo que está sucediendo al leer la fuente de glibc, por ejemplo. sysdeps/x86_64/crti.S .

TODO: ¿cómo hacer un paso para depurar ese código con la fuente? Modificando esos objetos en sí mismos es un gran dolor a menos que sepa artes oscuras .

    

Lea otras preguntas en las etiquetas