程序环境
程序环境分为翻译环境和执行环境
翻译环境:源代码转换为可执行的机器指令。
执行环境:用于实际执行代码。
编译链接
翻译环境
程序里面每个源文件都要先经过编译器处理生成他们相应的目标文件,最后这些目标文件和链接库一起通过连接器生成可执行文件。
因此,可以说翻译环境由编译和链接两块组成。
编译
其中编译又可以分为:预编译(预处理)、编译、汇编
想逐步分析生成什么,可以在 Linux 下用 gcc 编译器看看。
**1.预处理:**完成了头文件的包含 #include
#define 定义的符号和宏的替换
这两个都属于是文本操作。
预处理 选项 gcc -E test.c -o test.i
预处理完成之后就停下来,预处理之后产生的结果都放在test.i文件中。
可以发现 .i 文件里面写了一些关于头文件的阐释以及拉到最后看到代码里面define的一些替换,使代码简化
**2.编译:**把 c语言代码转化成汇编代码
要进行:语法分析、词法分析、语义分析、符号汇总
编译 选项 gcc -S test.c
编译完成之后就停下来,结果保存在test.s中。
**3.汇编:**把汇编代码转化成了二进制或者机器指令,生成符号表
. 汇编 gcc -c test.c
汇编完成之后就停下来,结果保存在test.o中。
生成的符号表是是对函数的声明赋予地址,成一个表。对没有定义的函数就给一个无意义的地址
test.o这个文件是elf格式的(分成段)
链接
链接就是去合并分段表、符号表的合并和符号表的重定位
即,最后将汇编产生的符号表(test.o add.o )还有链接库合并。
还是elf格式,产生了.exe 可执行文件
运行环境
程序执行的过程:
- 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序
的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。 - 程序的执行便开始。接着便调用main函数。
- 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值。
- 终止程序。正常终止main函数;也有可能是意外终止。