C语言《翻译环境和执行环境(预处理文件的生成)》

目录

1.C语言的翻译环境和执行环境

1.1 C语言的翻译环境

1.11 .i文件的生成

1.2 C语言的执行环境


1.C语言的翻译环境和执行环境

ANSI C美国国家标准协会(ANSI)设定的C语言标准)中存在两种环境

1.翻译环境:在这个环境中源代码被转换为可执行的机器指令

2.执行环境:实际应用于代码的实现

1.1 C语言的翻译环境

把源代码转换成可执行的机器指令需要经过编译与链接,而编译又细分为预处理(或者说预编译),编译,汇编。如图所示:

预编译:在gcc环境下以执行-E命令,test.c-->test.i 而test.i就是我们预处理之后的文件了。下面由具体观看.i文件的操作,预处理主要做的是文本操作,1.头文件的包含(#include),把头文件从库中引出放到文件中。2.把注释的文本去除。3.把#define定义的符号进行替换。4.条件编译。(#if,#endif,#elif等是在条件编译期间选择的)

编译:在gcc环境下-S命令,test.i-->test.s 产生编译后的test.s文件。编译主要作用:把c语言代码转换成汇编代码,其中涉及语法分析、词法分析、语义分析以及符号汇总。

汇编:在gcc环境下-c命令,把汇编文件.s转换为目标文件test.o(VS环境后缀.obj),它的作用是把汇编代码翻译成为二进制指令的机器语言,同时把文件中的函数标识等结合其所分配的符号地址形成符号表。(不同文件有各自的符号表)

链接:待编译完成后与进行链接,把该项目的所有文件链接,其主要分为1.合并段表(各个目标文件中被分为不同片段,不同文件的同一个段区合并在一起形成可执行程序中的各个段)。2.符号表的合并和重定位(每个目标文件.obj有各自的符号表,他们之中有相同或者不同的函数标识,相同名称的标识由于是不同文件产生故有不同的符号地址,于是统一重定位(声明只是个承诺,链接期间分配确切地址)形成最终的符号表,所以在不同文件调用函数都是从同一个地址出发的)(链接函数的定义,链接库里面的函数都是在这一层完成的

举个例子:

test.c函数标识Add的符号表匹配的地址,假设为0x0012ff40

int Add(int x, int y)
{
	return x + y;                //test0.c文件中的
}

 test1.c文件中有三个函数标识分别为printf,main,Add函数,该文件符号表匹配的Add地址为0x0025ff20 。于是最后链接完成得到可执行文件后两个Add就会重定义为同一个地址(以定义所在地址为主),以至于可以通过extern外部声明找到test0.c中的Add函数。但是有声明的

地址,不代表有这个函数的定义,最后会在链接中判断是否存在函数定义。

extern int Add(int x, int y);

int main()
{
	int a = 10;
	int b = 20;
	printf("%d\n", Add(a, b));            //test1.c文件中
	return 0;
}

值得一提的是:汇编阶段形成的符号表包含着函数标识及符号地址,这个地址并没有实际分配到空间,内存地址实际空间分配是在链接期间进行的。编译期间的符号地址是为链接器提供条件,方便寻找到该位置。具体符号地址取决于编译器,可能为偏移量或其他编码供其自己寻找。

 内容参考于下面两文章,仅作为学习参考。有问题可以评论区共同交流

(189条消息) 程序的静态链接(2):空间与地址分配_Aspiresky的博客-CSDN博客

关于汇编:汇编程序和符号表的用途是什么? 符号的地址是什么? | 码农家园 (codenong.com)

1.11 .i文件的生成

vs中属性——  C/C++  ——  预处理器  ——  预处理到文件(改为是)

再按仅编译(ctrl+F7)即可在debug文件中看到.i文件

 里面最后几行就是预处理后的程序代码

1.2 C语言的执行环境

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

  • 21
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 13
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值