目录
1.程序的翻译环境和执行环境
2.编译和链接
1.程序的翻译环境和执行环境
在ANSIC的任何一种实现中,存在两个不同的环境。
第一种是翻译环境,在这个环境中源代码被替换为可执行的机器指令。
第二种是执行环境,它用于实际执行代码。
2.编译和链接
1.翻译环境:
- 上图是一个源文件变成可执行程序的过程 ,上述过程也可以称为翻译环境,当我们生成可执行程序后想要程序运行起来,此时就需要一个运行环境。
- 而翻译环境又可以分为编译和链接。
- 源文件就是我们编写完程序后的.c文件,每一个源文件都会单独经过编译器(比如vs环境下是cl.exe)处理生成一个目标文件(.obj文件),再由链接器(vs环境下是link.exe)将多个目标文件链接在一起,再加上链接库(存放库函数等)最后生成我们的可执行程序(.exe文件)。
2.编译本身的几个阶段:
预处理:gcc test.c-E -o test.i(在Linux操作系统上的命令),只完成预处理,预处理后停止
- 头文件的包含(例如#include(预处理指令))
- #define定义符号的替换
- 删除注释
上述操作都叫做文本操作。
编译:gcc test.i -S (会生成test.s文件),把c语言代码转换为汇编代码。
- 语法分析
- 词法分析
- 语义分析
- 符号汇总(汇总的都是全局的符号,局部变量的符号不会汇总)
汇编:gcc test.s -c (生成一个test.o文件),把汇编代码转化成了二进制指令
- 形成符号表
链接:
- 合并段表:在Linux系统下test.o的二进制文件是以elf的各式来组织文件的,它会把文件分为几段,每个.o文件都有自己对应的段,然后把对应的段合并起来。
- 符号表的合并和重定位:把符号表合并起来,让所有的符号变量都能够找到合法的内存地址。
3.运行环境
程序执行的过程:
- 程序必须载入内存中,在有操作系统的环境中:一般这个由操作系统完成。在独立环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
- 程序的执行开始,接着调用main函数。
- 开始执行程序代码。这个时候程序将使用一个运行的堆栈,存储函数的局部变量和返回地址,程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程一直保留他们的值
- 终止程序。正常终止main函数;也有可能是意外终止。



