【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 文本文件------翻译环境------->.exe二进制文件------运行环境------->输出        

2. 程序编译、链接过程

编译:需要编译器

链接:需要链接器

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

3. 翻译环境

3.1 编译过程

 

3.1.1 预编译(预处理)

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

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

3.1.2 编译

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

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

3.1.3 汇编

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

  • 形成符号表

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

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

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

这里:

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

 

3.2 链接过程

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

3.2.1 合并段表

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

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

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

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

3.1.2 符号表的合并和重定位

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

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

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

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

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

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

 

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

例子:形成符号表

 

4. 运行环境

 

 

 

 

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

听风吹等浪起

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值