CTF-All-In-One/doc/1.5.1_c_basic.md
2017-08-05 20:44:45 +08:00

1.7 KiB
Raw Blame History

C 语言基础

从源代码到可执行文件

我们以经典著作《The C Programming Language》中的第一个程序 “Hello World” 为例,讲解 Linux 下 GCC 的编译过程。

#include <stdio.h>
main()
{
    printf("hello, world\n");
}
$gcc hello.c
$./a.out
hello world

以上过程可分为4个步骤预处理Preprocessing、编译Compilation、汇编Assembly和链接Linking

预编译

$gcc -E hello.c -o hello.i

预编译过程主要处理源代码中以 “#” 开始的预编译指令:

  • 将所有的 “#define” 删除,并且展开所有的宏定义。
  • 处理所有条件预编译指令,如 “#if”、“#ifdef”、“#elif”、“#else”、“#endif”。
  • 处理 “#include” 预编译指令,将被包含的文件插入到该预编译指令的位置。注意,该过程递归执行。
  • 删除所有注释。
  • 添加行号和文件名标号。
  • 保留所有的 #pragma 编译器指令。

编译

$gcc -S hello.c -o hello.s

编译过程就是把预处理完的文件进行一系列词法分析、语法分析、语义分析及优化后生成相应的汇编代码文件。

汇编

$gcc -c hello.s -o hello.o
或者
$gcc -c hello.c -o hello.o

汇编器将汇编代码转变成机器可以执行的指令。

链接

目标文件需要链接一大堆文件才能得到最终的可执行文件。链接过程主要包括地址和空间分配Address and Storage Allocation、符号决议Symbol Resolution和重定向Relocation等。