C语言_编译和链接

本文详细介绍了C语言程序从源代码到可执行程序的编译和链接过程,包括预处理、编译、汇编以及链接四个阶段,解释了如何处理多文件项目中的符号引用和重定位,以及程序在运行环境中的内存管理和执行流程。
摘要由CSDN通过智能技术生成

个人主页点这里~

欢迎大家学习更多知识!


编译和链接:

1.翻译环境和运行环境

在c语言实现的环境中,存在两个不同的环境.

      翻译环境:在这个环境中源代码被转换为可执行的机器指令(二进制指令)

      执行环境:执行实际代码.

eg:我们在编写代码时创建了test.c / add.c / max.c 等源文件,对于电脑他是无法读懂我们编写的代码,所以我们的代码需要经过这两个环境变化生成可执行程序.


2.翻译环境

根据上图我们的源程序经过翻译环境中怎么转换为可执行程序的呢?

翻译环境是由编译链接两大过程组成,对于编译又分成:预处理(有些书也叫预编

译)、编译、汇编三个过程。
过程:一个项目是由多个.c文件.h头文件构建的:
  1. 多个.c文件分别进入编译器,编译处理生成相对应的目标文件
  2. 多个目标文件和链接库一起经过链接器处理生成最终的可执行程序
  3. 链接库是指运行时库(它是支持程序运行的基本函数集合)或者第三方库

   我们画图了解一下


2.1 预处理(预编译)

在预处理此阶段, .c和.h文件会被处理为 .i 后缀的文件

此阶段的主要功能是:

  • 1.删除所有我们写的注释(注释是给我们程序猿看的,不是给电脑看的哈哈)
  • 2.将所有的#define删除,展开所有的宏定义
  • 3.处理所有的条件编译指令,eg:#if  #ifdef  #elif  #endif.....
  • 4.处理#iclude预编译指令,将包含的头文件的内容插入到预编译指令的位置,此过程是递归进行的,头文件里包含的头文件会逐个被打开
  • 5.添加行号和文件名标识,文便后续编译器生成调试信息等
  • 6.或保留所有的#pragma的编译器指令,编译器后续会使用。

   经过此阶段,生成的.i文件不会包含宏定义,头文件里内容都被插入到.i文件里


2.2 编译

此过程就是队.i文件进行词法分析,语法分析,语义分析及优化,生成相应以.s为后缀的汇编代码

        2.2.1 词法分析:

将代码程序输入扫描器,对程序进行词法分析,把代码的字符分割成一系列的记号

将会得到一下16种记号:

        2.2.2 语法分析:

此阶段会由语法分析器扫描器产生的的记号进行语法分析,从而产生语法树

比如:我们进行加法的编写等等

        2.2.3 语义分析:

经过语法分析得到的语法树,我们此阶段来完成语义分析,就是进行浅层面分析,主要完成声明,匹配,转换等,此阶段会报出编写的语法错误


   2.3 汇编:
汇编器是将汇编代码转转变成机器可执行的指令,每⼀个汇编语句几乎都对应⼀条机器指令。就是根据汇编指令和机器指令的对照表一一的进行翻译,也不做指令优化。

   2.4 链接:

链接把一堆文件链接在一起

链接过程主要包括:地址和空间的分配,符号决议,重定位等等

链接解决的是⼀个项目中多文件、多模块之间互相调用的问题 
根据我们之前的步骤,我们这里写的test.c和print.c源文件都单独经过编译器处理得到对应的目标文件 :     test.c --->test.o
        print.c --->print.o
我们在test.c文件中使用了一次print,c中的print函数时必须确切知道print函数的地址,但是由于两个文件时 单独编译的,所以 我们无法知道他的地址.
所以暂时把调用print   的指令的目标地址 搁置。等待最后链接的时候由
链接器根据引用的符号print 在其他模块中查找print 函数的地址,然后将 test.c 中所有引用到
print  的指令重新修正,让他们的目标地址成为真正的print 函数的地址,这个地址修正的过程叫做:重定位.

3.运行环境
1. 程序必须载入内存中。在有操作系统的环境中:一般这个由操作系统完成。在独立的环境中,程序的载入必须由手工安排,也可能是通过可执行代码置入只读内存来完成。
2. 程序的执⾏便开始。接着便调⽤main函数。
3. 开始执行程序代码。这个时候程序将使用一个运行时堆栈(stack),存储函数的局部变量和返回地址。程序同时也可以使用静态(static)内存,存储于静态内存中的变量在程序的整个执行过程⼀直保留他们的值。
4. 终止程序。正常终止main函数;也有可能是意外终止。

分享就到这里,一起加油!

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

路过的墙颈鹿

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

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

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

打赏作者

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

抵扣说明:

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

余额充值