¿Cuáles son todos los detalles internos que pasan dentro del sistema informático cuando compilo y ejecuto un programa?

Entonces sucede lo siguiente:

  • Primero se ejecuta el preprocesador, que realiza sustituciones macro entre otras cosas.
    comando: cpp file.c equivalente a gcc -E file.c
    La salida es como se ve aquí: deepakkarki / preprocess.c
  • A continuación, se ejecuta el compilador que convierte este archivo .C preprocesado a .S (archivo de ensamblaje)
    comando: gcc -S file.c
    salida: deepakkarki / asm_output.s
  • Luego, el ensamblador se ejecuta en el archivo .S para crear un archivo de objeto .O.
    comando gcc -c file.s
    salida: deepakkarki / obj.o

    Se crea un .o para cada archivo .C. Pero ahora las funciones se utilizan en todos los archivos, por lo que los archivos .O contienen símbolos cuando la función o variable utilizada en un archivo no está definida allí. por ejemplo, deepakkarki / obj.o: test.c \ 00main \ 00printf en la línea 5

  • Ahora el enlazador toma múltiples archivos .O y los une para formar un solo archivo ejecutable.
    gcc -o output_file_name file.o
  • ¡Pero espera, hay más! En caso de que la función sea parte de una biblioteca dinámica (piense en archivos .so), incluso este “ejecutable” final contendrá símbolos.
    El exe está aquí: deepakkarki / exe.exe
  • Finalmente, el cargador se ejecuta cuando dice ./my_file desde la línea de comandos. Esto carga el programa en la memoria, se llama a un enlazador de tiempo de ejecución para referencias de funciones a bibliotecas de tiempo de ejecución. Vincula el “ejecutable” obtenido anteriormente para crear una imagen final que luego se carga en la memoria.

Luego, el programa se ejecuta feliz para siempre (hasta que se llame a _exit)