由于 visual studio 这一宇宙第一IDE的存在,使我们开发C程序事半功倍,但是同时也造成了很多人对一个C源程序实际的编译过程一无所知,所以本文讲给大家介绍一下一个C源程序从文本到可执行程序的转变过程。
1. 程序环境
我们将程序所处的环境称为程序环境,而程序环境分为翻译环境与运行环境。
- 翻译环境:创造可执行文件的环境
- 运行环境:用户使用可执行文件的环境
首先,有一个源文件 test.c,接下来进入
1.1 翻译环境
翻译环境又分为编译和链接两个步骤。
1.1.1 编译:
编译分为预处理,编译,汇编三个步骤。
- 预处理 (-E -o 生成 test.i)
头文件的包含
注释的替换(替换为空格)#define标识符的替换
宏替换
总结:文本替换。
- 编译 (-S 生成汇编代码test.s)
语法分析
词法分析词义分析
符号汇总(汇总全局变量,局部变量只有在运行时才创建,符号汇总时不汇总)
- 汇编(-c 生成目标文件test.o)
形成符号表
汇编代码转换为二进制指令
程序运行到这里,就完成了编译编译过程,这时我们得到一个二进制文件,但注意,这个二进制文件可不是我们想要的可执行二进制文件 exe,要得到 exe,我们还得进行链接过程。
1.1.2 链接:
链接包含如下过程. gcc test.o 生成test.exe可执行文件(windows下为.exe) - 符号表合并 - 段表的合并 - 重定位 经过链接,我们便得到了梦寐以求的可执行文件 test.exe 。1.2 运行环境
1.2.1 程序必须载入到内存中
- 程序加载到内存中一般借助操作系统的帮助。
- 无操作系统的硬件系统想要将程序加载到内存中,就要通过外部设备烧录。
1.2.2 调用main函数
- main 函数是程序的入口。
1.2.3 开始执行程序
- 使用运行时堆栈(栈帧)存储函数的局部变量和返回地址。程序同时亦可以使用静态(static)内存存储在静态内存中的变量在程序的整个执行过程中一直保留着他们的值.
1.2.4 程序中止
- 程序运行结束。
2. linux验证程序环境
1.1 Linux常用命令
ls list 列出当前文件夹下文件
cd change directory 改变当前目标文件夹
cd .. 返回上一级目录
pwd 打印当前工作目录
rm remove 删除
rm -f 删除文件
rm -rf 递归删除,删除所属文件夹所有内容
mkdir 创建文件夹
2.1 vim 编辑器
vim test.c
三种模式
1.普通模式(刚进入)
2.插入模式(写代码) i进入 按”ESC“推出到普通模式
3.命令行模式 在普通模式下 ":wq"(保存退出),":"进入插入模式
G 直接跳到最后一行
gcc(cc) C语言的一种编辑器
g++ C++语言的一种编辑器
3.vim实现程序环境
gcc test.c [-0 test] //[设置编译后生成可执行文件名为test],要在当前目录下
gcc test.c -E -o test.i //预处理完成后停下,生成test.i
gcc test.c -S //生成 test.s 汇编代码
gcc test.c -c //生成 test.o 目标文件
gcc test.o //生成 test.exe可执行文件
linux下可执行文件格式为elf格式
readelf 读取elf格式的工具
readelf test.o -s
本节相关内容可参考
《程序员的自我修养》