第二章
编译和链接
这章比较笼统,都是概念,熟悉基本流程的人,建议不看。
记录一些基本流程
拿GCC来说
用GCC编译链接生成可执行文件的过程分为下面4个步骤
Prepressing,Compilation,Assembly,Linking
Prepressing 预处理
从.c -> .i (gcc -E)
主要是处理,前缀为‘#’的语句
define的直接替换
对define这种,从我观察应该是这样
对源文件类似.c直接扫描 看到define的符号直接加到表中
然后在替换的时候会做递归检查,直到符号是最终定义。
所以这个与define的顺序没有太大关系了,只要不循环嵌套
类似这种
#define M (N + 1)
#define N 2
这种在用到M的时候,会先替换成 (N + 1)但是发现替换的表达式中还有未决symbol,那么
就再进行替换 (2 + 1)
表中并不会直接写成 M (2 + 1),至少我看到的GCC行为是这样。
include的也是直接导入
另外预编译选项 #ifdef 之类的会处理掉,删掉所有注释
#pragma是要被保留给编译器的,这是编译器选项,例如 pragma pack是用来指定字节对齐标准的
Compilation 编译
从 .i -> .s (gcc -S)
现在的GCC版本都把预编译和编译做到了一个可执行程序中 -> ccl
编译的主要过程
扫描,语法分析,语义分析,源代码优化,代码生成,目标代码优化
Source code --Scanner--> Tokens --Parser--> Syntax Tree
--Semantic Analyzer--> Commented Syntax Tree --Source code Optimizer--> Intermediate Representation
--Code Generator--> Target Code --Code Optimizer-->Final Target Code
Assembly 汇编
从 .s -> .o (gcc -c) -->汇编器as
Linking 链接
ld做的事情
link的时候由于每个源文件都是单独编译,那么必须处理一些外来的symbol
包括函数和全局变量