Proceso de compilación de GCC: preprocesamiento->compilación->ensamblaje->enlace

Tabla de contenido

introducción

 Descripción general

1. Pretratamiento

Dos, compila

3. Compilación

4. Enlaces

Resumir


introducción

Al utilizar el entorno de desarrollo integrado (IDE) para la programación en lenguaje C, después de hacer clic en el botón " Compilar ", el proceso de generación de todo el programa C desde el código fuente hasta el archivo ejecutable se completará automáticamente. El IDE realizará el proceso de compilación del lenguaje C para nosotros en segundo plano, convirtiendo el código fuente en el archivo ejecutable final. Aunque el IDE oculta los detalles de bajo nivel, comprender el proceso de compilación sigue siendo valioso para el programador.

 Descripción general

gccAmbos g++son parte de la colección de compiladores GNU (GCC para abreviar), que se gccusan para compilar código de lenguaje C y g++se usan para compilar código de lenguaje C++. Su proceso de compilación es similar en la mayoría de los casos , pero dependiendo de la extensión del archivo de entrada y de algunas opciones predeterminadas, llamarán a diferentes interfaces de compilación, a saber, C front end o C++ front end.

La siguiente es una descripción general del proceso de compilación para gccyg++

  1. Preprocesamiento (Preprocessing): En primer lugar, se preprocesa el archivo de origen. El preprocesador procesará las directivas de preprocesamiento en el código fuente, como #las directivas que comienzan con , como #include, #defineetc., y ampliará las definiciones de macro. El código preprocesado genera un .iarchivo , generalmente en un directorio temporal.

  2. Compilación: A continuación, la interfaz del compilador compila el código fuente preprocesado en código ensamblador ( .sarchivo ). Esta fase comprueba errores sintácticos y semánticos y realiza optimizaciones , pero no genera código ejecutable.

  3. Ensamblado (Assembling): El ensamblador (as) convierte el código ensamblador en código máquina y genera un archivo objeto ( .oarchivo ).

  4. Vinculación: finalmente, el vinculador ( ld) vincula el archivo de objeto con los archivos de biblioteca requeridos para generar el archivo ejecutable final.

Tomemos un ejemplo simple del proceso de compilación del programa C en el entorno Linux para profundizar nuestra comprensión.

Ejemplo de código (principal.c):

#include<stdio.h>

int main(){
    printf("Hello Linux\n");
    return 0;
}

1. Pretratamiento

El preprocesamiento es el primer paso en el proceso de compilación, que procesa #las directivas de preprocesamiento que comienzan con y expande las definiciones de macro. El preprocesador realiza las siguientes tareas principales:

  • Instrucción de procesamiento #include: inserte el contenido del archivo de encabezado especificado en el código fuente. De esta forma, las declaraciones y definiciones de otras funciones o variables se pueden utilizar en el archivo fuente.

  • Definiciones de macros de proceso: expanda las macros definidas en el código en expresiones o declaraciones correspondientes. Por ejemplo, reemplazará #define MAX_VALUE 100todo con en el código fuente .MAX_VALUE100

  • Procesar instrucciones de compilación condicional: como #ifdef, #ifndef, #ifetc. Estas instrucciones juzgan si compilar algunos bloques de código de acuerdo con las condiciones.

El código preprocesado produce un solo .iarchivo, que es un archivo intermedio con todas las macros expandidas y todos los encabezados incluidos.

ejemplo de sintaxis

gcc -E main.c -o main.i

 En el comando -E es para permitir que el compilador salga después del preprocesamiento sin un proceso de compilación posterior, y -o es para especificar el nombre del archivo de salida.

El resultado de usar esta instrucción es insertar todo el contenido del archivo stdio.h en main.c para formar el archivo main.i.

Se puede ver que el archivo main.i después del preprocesamiento es obviamente mucho más grande que el archivo main.c. Revisemos el archivo main.i, porque main.i todavía es un archivo de texto en este momento.

(Use el comando head para ver el archivo main.i)

Dos, compila

La compilación es la segunda etapa del código preprocesado. Un front-end del compilador (como cc1o cc1plus) toma el código preprocesado y lo convierte en código ensamblador. Durante la fase de compilación, el compilador realiza las siguientes tareas principales:

  • Verificación gramatical y semántica: el compilador verifica si el código cumple con las reglas gramaticales de C/C++ y realiza un análisis semántico para asegurarse de que el código no tenga errores lógicos.

  • Generar una representación intermedia: el compilador convierte el código en una representación intermedia, generalmente una representación independiente del hardware de bajo nivel.

  • Optimización: el compilador puede optimizar la representación intermedia para mejorar la eficiencia de ejecución del programa y la calidad del código.

La fase de compilación no genera un archivo ejecutable, sino que convierte el código en código ensamblador, generalmente guardado como .sun archivo.

ejemplo de sintaxis

gcc -S main.i -o main.s

En el comando -S hace que el compilador se detenga después de la compilación sin un proceso de compilación posterior, y -o especifica el nombre del archivo de salida.

El tamaño del archivo de ensamblaje compilado ya es muy pequeño, mucho más pequeño que el archivo main.i después del preprocesamiento.

Una vez finalizado el proceso de compilación, se generará el código ensamblador test.s del programa, que también es un archivo de texto . Vamos a ver.

 La figura es el código ensamblador en main.s.

3. Compilación

En la etapa de ensamblado, el ensamblador ( as) toma el código ensamblador generado por la compilación y lo convierte en código máquina. Las tareas del ensamblador incluyen:

  • Convierta el código de ensamblaje en código de máquina: traduzca las instrucciones de ensamblaje en código de ensamblaje en instrucciones de máquina que una arquitectura de hardware específica pueda entender.

  • Generar archivos de objetos: genere uno o más archivos de objetos ( .oarchivos), uno para cada archivo fuente o unidad de compilación.

Los archivos de objetos son representaciones binarias de código de máquina, pero aún no son programas ejecutables finales porque algunas referencias de símbolos pueden permanecer sin resolver.

ejemplo de sintaxis

gcc -c main.s -o main.o

opción en el comando -c, le dice a gcc que solo compile, no que vincule. Por lo tanto, este comando solo convertirá el código ensamblador en un archivo de objeto y no generará un archivo ejecutable. -o es para especificar el nombre del archivo de salida.

Un archivo de objeto test.oes una representación binaria de código de máquina que se puede usar como entrada para vincular para producir el ejecutable final.

4. Enlaces

  • Un enlazador toma uno o más archivos de objeto y los archivos de biblioteca requeridos y los combina en el ejecutable final.
  • El vinculador resuelve las referencias de símbolos en los archivos de objetos, encuentra las definiciones de símbolos correspondientes y reubica los símbolos para que apunten correctamente a sus definiciones.
  • Combine archivos de biblioteca para producir un ejecutable completo que contenga todo el código de máquina y los símbolos resueltos.

ejemplo de sintaxis

gcc main.o -o main

comando es un comando gcc que vincula gcc main.o -o mainun archivo de objeto ( main.o) en un archivo ejecutable ( ). mainEn este comando, no usamos -copciones, por lo que gcc realizará la operación de enlace para generar el archivo ejecutable final.

Cuando se ejecuta el comando gcc main.o -o main, gcc main.ovinculará el archivo de objeto junto con los archivos de biblioteca requeridos (si corresponde) y generará el archivo ejecutable final main. Este archivo ejecutable es un programa C que puede ejecutarse en Linux.

 Al ejecutar ./mainel comando, se ejecuta mainel ejecutable llamado . Este es el archivo ejecutable del programa C que generamos gccanteriormente con el comando.

Resumir

El proceso de generación de un programa ejecutable se divide en cuatro pasos:

  1. Desde un archivo .c hasta un archivo .i, este proceso se denomina preprocesamiento.
  2. Del archivo .i al archivo .s, este proceso se denomina compilación.
  3. Desde el archivo .s hasta el archivo .o, este proceso se denomina ensamblado.
  4. Desde archivos .o hasta archivos ejecutables, este proceso se denomina vinculación.

En el entorno de desarrollo integrado, después de hacer clic en el botón "Compilar", el IDE completará automáticamente las cuatro etapas anteriores sin realizar manualmente cada paso. Si no hay errores de compilación, el ejecutable final se crea y se puede ejecutar directamente en el IDE.

Aunque el IDE nos brinda herramientas de compilación convenientes, sigue siendo importante que los programadores comprendan el proceso de compilación del lenguaje C, especialmente al resolver algunos errores de compilación u optimizar, comprender el proceso subyacente puede ayudarnos a comprender mejor y mejorar el código.

Supongo que te gusta

Origin blog.csdn.net/weixin_57082854/article/details/132152404
Recomendado
Clasificación