I. Construction process

precompiled

gcc -E source.c -o source.i
Copy the code

Handles precompiled instructions that begin with “#”

  • Remove all “#define” and expand all macro definitions.
  • Handle all conditional precompiled instructions, “#if”, “#ifdef”.
  • Process the “#include” directive by inserting the included file at the location of the precompiled directive.
  • Remove the comments
  • Keep all #pragma compiler directives.
  • Add line numbers and file name identifiers

The source code

#include <stdio.h>

#pragma pack(4)

#define3.1415926 PI?

int main(a)
{
    #ifdef WINOS
        printf("WIN OS\n");
    #else
        printf("MAC OS\n");
    #endif
    printf("PI = %f\n", PI);
    printf("Hello World! \n");
    return 0;
}
Copy the code

After the precompiled

· · · · · · · · · · · · #2 "source.c" 2

#pragma pack(4)

int main(a)
{



        printf("MAC OS\n");

    printf("PI = %f\n".3.1415926);
    printf("Hello World! \n");
    return 0;
}
Copy the code

compile

After a series of lexical analysis, grammar analysis, semantic analysis and optimization, assembly code files are generated. Compilation is based on C files as compilation units

gcc -S source.i -o source.s
Copy the code

assembly

Assembler code into machine instructions to generate object files.

gcc -c source.s -o source.o
Copy the code

link

A number of variables and functions constitute a module, a source file is called a compilation unit, the link is mainly to deal with symbolic references between each compilation unit. Including address and space allocation, symbol resolution, relocation.

Ii. Compilation process

  • Lexical analysis
    • Decompose source code into word symbols.
  • Syntax analysis
    • Context-free algorithms.
    • Generate syntax tree.
    • Check for syntax errors (mismatched parentheses, missing operators, and so on).
  • Semantic analysis
    • Static semantic analysis (semantics that can be determined by the compiler).
    • Check for semantic errors (matches between declarations and types).
  • To optimize the
    • Source level optimization:
      • The syntax tree is converted into intermediate code (three address codes).
      • Optimize out some code that can be determined at compile time, for example the expression 2 + 6 will be optimized to the value 8.
      • The resulting intermediate code is machine independent.
    • Code generator:
      • Convert intermediate code to target machine code.
    • Target machine code optimization

The basic process of linking (static linking)

The relocation compilation unit main.c references the foo() function in the other compilation unit func.c. The address of foo() is not known when main.c is compiled, so the address of foo() in the directive is shelved. When linking, the linker looks for the real address of foo() in the func module and replaces the address in the directive referencing foo() in main with the real address.