程序环境(翻译环境和执行环境)

1.翻译环境和执行环境

在ANSI C的任何一种实现中,存在两个不同的环境
第一种是翻译环境,在这个环境中源代码被转换为可执行的机器指令
第二种是执行环境,用于实际执行代码

2.翻译环境

翻译环境进行编译和链接
编译过程分为三步
①.预处理(预编译)
预编译过程把源文件变成.i文件,预处理完之后就停下来,预处理完的结果放在test.i中主要处理以#开头的预编译指令,比如#include、#define等
主要是:
头文件的包含
注释的删除
#define定义符号的替换
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
相当于根据预处理指令组装新的C/C++程序。经过预处理,会产生一个没有头文件(都已经被展开了)、宏定义(都已经替换了),没有条件编译指令(该屏蔽的都屏蔽掉了),没有特殊符号的输出文件,这个文件的含义同原本的文件无异,只是内容上有所不同。
②.编译

编译是把c语言代码翻译成汇编代码 c语言代码->汇编代码
经历 语法分析,句法分析,语义分析,符号汇总
词法分析:
词法分析就是把源代码变成一个个词,即token
每个token的类型有关键字、标识符、字面量、特殊符号等。
语法分析:
语法分析就是建立语法树,一个语句对应一颗语法树
例:
在这里插入图片描述

在这里插入图片描述
语义分析:
有些符合语法的句子在语义层面不合法,比如两个指针相乘。
编译器所能分析的是静态语义,即编译器可以确定的语义,另外一种是动态语义,即运行期语义
在这里插入图片描述

在这里插入图片描述

③.汇编
将汇编代码转换成二进制指令(二进制指令)
没有复杂语法,也没有语义,也不需要优化,只需要一一对应的翻译即可,最后生成目标文件,Windows中的.obj,Linux中的.o。
形成符号表

链接
链接主要包括
①.合并段表
②.符号表的合并和符号表的重定位

链接过程主要包括地址和空间分配、符号决议(符号绑定/地址绑定)、重定位等。
各个模块是单独编译的,编译完成之后链接起来的过程叫静态链接。
编译时,对于其他模块的各符号地址都是未知的,先暂时写成0,这里会留一个重定位入口,
链接时,各个符号都有了地址之后,把各模块中各符号的地址都刷新成正确的值,这个过程叫重定位。
动态链接库:Windows中的.dll,Linux中的.so
静态链接库:Windows中的.lib,Linux中的.a

链接程序的主要工作就是将有关的目标文件彼此相连接,也就是将在一个文件中引用的符号同该符号在另外一个文件中的定义连接起来,使得所有的这些目标文件成为一个能够被操作系统装入执行的统一整体。在此过程中会发现被调用的函数未被定义。需要注意的是,链接阶段只会链接调用了的函数/全局变量,如果存在一个不存在实体的声明(函数声明、全局变量的外部声明),但没有被调用,依然是可以正常编译执行的。

隔离编译,一起链接

在这里插入图片描述
组成一个程序的每个源文件通过编译过程转换成目标代码(object code)
每个目标文件由链接器(linker)捆绑在一起,形成一个单一而完整的可执行程序
连接器同时也会引入标准C函数库中任何被该程序所用到的函数,而且它可以搜索程序员个人的程序库,将其所需要的函数链接到程序中

test.c 预处理得到test.i编译得到test.s汇编得到test.o再与链接库链接得到test.exe

3.运行环境(执行环境)

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

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值