in

Compilar un programa en C: – Detrás de escena

gfg 200x200 min

C es un lenguaje de nivel medio y necesita un compilador para convertirlo en un código ejecutable para que el programa pueda ejecutarse en nuestra máquina.

¿Cómo compilamos y ejecutamos un programa en C?
A continuación se muestran los pasos que usamos en una máquina Ubuntu con compilador gcc.

Compilacion

  • Primero creamos un programa en C usando un editor y guardamos el archivo como filename.c
 $ vi filename.c
  • El diagrama de la derecha muestra un programa simple para sumar dos números.

compil31

  • Luego compílelo usando el siguiente comando.
 $ gcc –Wall filename.c –o filename
  • La opción -Wall habilita todos los mensajes de advertencia del compilador. Se recomienda esta opción para generar un mejor código.
    La opción -o se utiliza para especificar el nombre del archivo de salida. Si no usamos esta opción, entonces se genera un archivo de salida con el nombre a.out.

compil21

  • Después de que se genera el ejecutable de compilación y ejecutamos el ejecutable generado usando el siguiente comando.
 $ ./filename 

¿Qué incluye el proceso de compilación?
El compilador convierte un programa en C en un ejecutable. Hay cuatro fases para que un programa en C se convierta en ejecutable:

  1. Preprocesamiento
  2. Compilacion
  3. Montaje
  4. Enlace

Al ejecutar el siguiente comando, obtenemos todos los archivos intermedios en el directorio actual junto con el ejecutable.

 $gcc –Wall –save-temps filename.c –o filename 

La siguiente captura de pantalla muestra todos los archivos intermedios generados.

compil4

Veamos uno por uno qué contienen estos archivos intermedios.

Preprocesamiento

Esta es la primera fase a través de la cual se pasa el código fuente. Esta fase incluye:

  • Eliminación de comentarios
  • Expansión de macros
  • Ampliación de los archivos incluidos.
  • Compilación condicional

La salida preprocesada se almacena en el nombrearchivo.i. Veamos qué hay dentro de filename.i: using $ vi nombrearchivo.i
En la salida anterior, el archivo fuente está lleno de mucha, mucha información, pero al final nuestro código se conserva.
Análisis:

  • printf contiene ahora a + b en lugar de agregar (a, b), eso se debe a que las macros se han expandido.
  • Los comentarios se eliminan.
  • #include falta en su lugar, vemos mucho código. Entonces, los archivos de encabezado se han expandido e incluido en nuestro archivo fuente.

Compilando

El siguiente paso es compilar filename.i y producir un; archivo de salida compilado intermedio filename.s. Este archivo está en las instrucciones de nivel de ensamblaje. Veamos este archivo usando $ vi nombrearchivo.s

imagen

La instantánea muestra que está en lenguaje ensamblador, que el ensamblador puede entender.

Montaje
En esta fase, el nombre de archivo.s se toma como entrada y se convierte en filename.o por ensamblador. Este archivo contiene instrucciones a nivel de máquina. En esta fase, solo el código existente se convierte a lenguaje de máquina, las llamadas a funciones como printf () no se resuelven. Veamos este archivo usando $ vi nombrearchivo.o

compil7

Enlace

Esta es la fase final en la que se realizan todos los enlaces de las llamadas a funciones con sus definiciones. Linker sabe dónde se implementan todas estas funciones. Linker también hace un trabajo adicional, agrega un código adicional a nuestro programa que se requiere cuando el programa se inicia y finaliza. Por ejemplo, hay un código que se requiere para configurar el entorno, como pasar argumentos de línea de comando. Esta tarea se puede verificar fácilmente usando $ tamaño nombrearchivo.o y $ tamaño nombre de archivo. A través de estos comandos, sabemos cómo aumenta el archivo de salida de un archivo objeto a un archivo ejecutable. Esto se debe al código adicional que agrega el vinculador con nuestro programa.

compil8

Tenga en cuenta que GCC por defecto hace un enlace dinámico, por lo que printf () está enlazado dinámicamente en el programa anterior. Consulte esto, esto y esto para obtener más detalles sobre enlaces estáticos y dinámicos.
Este artículo es una contribución de Vikash Kumar. Escriba comentarios si encuentra algo incorrecto o si desea compartir más información sobre el tema discutido anteriormente.

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

apple touch icon@2

¿Qué es HEAD en Git?

edit

Gran Bretaña vs Reino Unido – Diferencia y comparación