版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
过程:
$gcc hello.c
$./a.out
结果:Hello World
包含四个步骤:预处理、编译、汇编、链接。
预处理:
$gcc -E hello.c -o hello.i
主要处理规则:
1)展开宏定义;
2)条件编译“#if”,“#ifdef”,“#elif”,“#else”,“#endif”;
3)处理预编译指令(#include),将文件插入到改指令位置,递归进行;
4)删除所有注释
5)添加行号和文件名标识(#2,“hello.c” 2);
6)保留所有#pragma编译器指令。
编译:
$gcc -S hello.i -o hello.s
将预处理完的文件进行一系列词法分析,语法分析,语义分析及优化后生产相应的汇编代码文件,是整个程序构建的核心部分。
汇编:
$gcc -c hello.s -o hello.o or $gcc -c hello.c -o hello.o
汇编器(as)将汇编代码转变成机器可以执行的指令,每一个汇编语句几乎都对应一条机器指令。汇编过程简单。
链接:
连接器(ld)将一些程序依赖的静态库和动态库链接到一起形成一个可执行的程序。链接过程包括:地址和空间分配、符号决议和重定位。
C程序的存储空间分配:
内存分区
程序代码区(code area):
存放函数体的二进制代码
静态数据区(data area):
亦称全局数据区,还分“data”段和“bss”段
Data: 已初始化的全局变量、已初始化的局部静态变量。
Bss:未初始化的全局变量、未初始化的局部静态变量。
全局数据区:一般常量,字符串常量。
堆区(heap area):
一般由程序员分配和释放,若程序员不释放,程序运行结束后由操作系统回 收,malloc(), calloc(),free()等函数操作这段内存。
栈区(stack area):
由系统自动分配释放,存放函数的形参,局部变量,自动变量等, 生命周期在函数调用结束时结束。
命令行参数区:
存放命令行参数和环境变量的值,如通过main()函数传递的值。