编译链接过程
编译链接过程分析
Linux中程序的链接过程如下:
#include<stdio.h>
int main()
{
printf("hello\n");
}
预编译
gcc -E main.c -o main.i
- 删除#define,展开宏定义
- 处理条件编译指令,#if,#ifdef,#else
- 处理#include预编译指令,将被包含的文件插入到该编译指令的位置。(递归执行)
- 删除所有的注释,// /* */
- 添加行号和文件名标识,以便出现错误或者警告能显示行号
- 保留#pragma编译器指令
编译
gcc -S main.i -o main.s
- 词法分析
- 语法分析
- 语义分析
- 中间代码生成
- 目标代码优化
汇编代码
汇编
gcc -c main.s -o main.o
翻译成二进制文件
二进制文件
链接
gcc main.o -o main
合并符号表 合并section 调整段大小和段起始位置
- 地址和空间分配
- 符号决议(绑定)
- 符号重定位
编译的优化
array[index] = (index + 4) * (2 + 6)
原先汇编
优化后汇编:
乘法由基址比例变址寻址的lea指令完成,最后由mov指令完成赋值