【C语言进阶】程序的翻译、执行

目录

1. 程序的翻译环境和运行环境

2. 程序编译、链接过程

3. 翻译环境

3.1 编译过程

3.1.1 预编译(预处理)

3.1.2 编译

3.1.3 汇编

3.2 链接过程

3.2.1 合并段表

3.1.2 符号表的合并和重定位

4. 运行环境


1. 程序的翻译环境和运行环境

.c 文件是源文件或者源程序

但是在电脑中运行的文件都是 .exe 可执行文件

所以 .c的源文件需要经过 编译+链接 变成 .exe可执行文件

【C语言进阶】程序的翻译、执行_第1张图片

.c 文本文件------翻译环境------->.exe二进制文件------运行环境------->输出        

【C语言进阶】程序的翻译、执行_第2张图片

2. 程序编译、链接过程

【C语言进阶】程序的翻译、执行_第3张图片

编译:需要编译器

链接:需要链接器

每一个源文件经过编译器都会生成一个目标文件

3. 翻译环境

3.1 编译过程

【C语言进阶】程序的翻译、执行_第4张图片

 

3.1.1 预编译(预处理)

预处理阶段:文本操作-----> 将.c 文件变成 .i 文件

  • 头文件的包含:拷贝头文件
  • 删除注释: 使用空格代替注释(包括头文件中的注释)
  • #define 定义的替换

3.1.2 编译

编译阶段:将C语言代码翻译成汇编代码------->将.i 文件变成 .s 文件

  • 语法分析:检查C语言代码有没有错误
  • 词法分析:将C代码进行拆解,比如哪些是符号,哪些是操作符等等
  • 语义分析:读懂语义,才能将C代码翻译成汇编
  • 符号汇总:将全局变量、函数名等符号,进行汇总,为链接做准备

3.1.3 汇编

汇编阶段:将汇编文件翻译成二进制文件------->将.s 文件变成 .obj 文件

  • 形成符号表

每个源文件都会生成对应的目标文件

编译阶段将全局变量、函数名等符号,进行汇总

而汇编将编译阶段汇总的符号生成一个符号表,就是将符号和地址对应起来,生成一个类似表格一样的结构

【C语言进阶】程序的翻译、执行_第5张图片

这里:

  • Add 0x000的地址是没有用的,但是main程序的文件中包含它,那就要生成一个地址,现在还没将具体的地址链接起来,所以这个地址是无效的
  • 对应的add.c 中有个函数,会生成符号表,例如 Add 0x100
  • main函数也会形成符号表
  • 只有函数名、全局变量等才会在编译阶段进行符号汇总,然后汇编阶段形成符号表

 

3.2 链接过程

将多个目标文件经过链接器链接,生成可执行程序.exe

【C语言进阶】程序的翻译、执行_第6张图片

3.2.1 合并段表

.obj 目标文件有自己的固定格式(elf文件格式),都被分成了几个段

将不同的目标文件链接在一起

这样,对应段上的数据就会放到一起去了

不管有多个.obj目标文件,最后只能生成一个.exe可执行程序

3.1.2 符号表的合并和重定位

【C语言进阶】程序的翻译、执行_第7张图片

这时候,需要进行符号表的合并和重定位

我们知道main函数里面那个Add的地址是错误的,且Add是有重名的

所以将两个Add合并,取有效的Add地址,这里是 0x 100,相当于符号表的重定位

main函数没有冲突,直接生成符号表

这样函数名和地址对应起来,需要的时候直接去地址中找就行了

【C语言进阶】程序的翻译、执行_第8张图片

【C语言进阶】程序的翻译、执行_第9张图片

  • 如果Add的代码没有了
  • 那么合并符号表的时候,就会找不到Add的地址,就会报错
  • 所以报错是链接错误、而符号表的合并就是在链接期间完成的

 

  • 因为main函数文件那个Add只是声明函数,之前函数章节介绍过,声明是告诉这里可能有个函数长啥样,但是具体有没有无所谓

例子:形成符号表

【C语言进阶】程序的翻译、执行_第10张图片

 

4. 运行环境

【C语言进阶】程序的翻译、执行_第11张图片

 

 

 

 

 

你可能感兴趣的:(【C语言学习】,c语言,visual,studio)