带你认识程序环境

目录

前言

一、详解编译和链接

        1.编译和链接的关系

        2.编译和链接过程

                2.1预编译过程

                2.2编译过程

                2.3 汇编过程

                2.4 链接过程

        二.运行环境


前言

在ANSI C的任何一种实现中,存在两个不同的环境

第一种是翻译环境,把源代码转变成可执行的机器码

第二种是执行环境,负责执行代码


一、详解编译和链接

        1.编译和链接的关系

我们用一张图来表示翻译的大概过程

 

每一个源文件都会单独通过编译器(cl.exe)生成目标文件,即后缀为obj的文件,然后链接器(link.exe)会把目标文件和链接库链接在一起,生成可执行文件,即.exe文件。这就是编译和链接的大概过程。链接库就是提供你使用的一些库函数的信息。现在的集成开发环境(IDE)可以包括编辑,编译,链接,调试等一系列功能。


        2.编译和链接过程

编译过程分为预编译,编译和汇编三个过程,由于现在的很多编译器功能很完备了,想要更仔细了解,我们可以在Linux环境下面演示,这里用的是gcc编译器集。

                2.1预编译过程

用命令(-E)让程序停在预编译刚结束的时候,这时候我们可以看见预编译过程会生成的一个文件

 

我们可以看见,除了自己写的main函数外,该文件还多了很多代码,其实这些代码就是包含的头文件里面的信息,但是我们发现注释都不见了,宏也会被替换。所以我们就可以知道预编译的功能—处理#include,即把头文件的信息包含进来;去除注释;替换宏。

我们可以发现预编译完成的都是一些文本操作。

                2.2编译过程

用命令(-S)可以让代码在编译后停下来

 

 这就是编译后生成的文件里面的信息,所以编译就是吧代码转换成汇编代码,不过这个过程包含了词法分析语法分析语义分析符号汇总,这里讲解一下符号汇总,其他的可以到汇编原理课程学习。

那么什么是符号汇总呢?

我们知道,翻译过程会生成一个可执行程序(a.out),这是一个二进制文件,并且是elf格式,这个文件里有一个符号表,我们在Linux下面可以用一个readelf的工具来来查看这些符号。

#include<stdio.h>
int g_val=345;
int Add(int x,int y)
{
    return x+y;
)

int main()
{    
    int a=4;
    int b=6;
    int c=Add(a,b);
    printf("%d",c);
    return 0;
}

查找上面这个程序的符号表,可以发现一些符号

 江江,函数和全局变量的符号都被包含起来了,神奇吧。这就是符号汇总,为什么需要符号汇总呢?这和链接有很大关系。

                2.3 汇编过程

汇编可不是生成汇编代码,而是把汇编代码转换成二进制文件,这就是可执行程序,它也是elf格式的。这个过程还会生成符号表,就是符号名+符号地址,说了这么久,符号表到底是干嘛的?我们接着往下看。


                2.4 链接过程

链接主要实现两个功能:合并段表;合并符号表和重定位

在翻译结束后,生成了多个可执行程序,这些程序都是elf格式的,这种文件不同的数据是放在不同的段的,合并段表就是把相同的段合并在一起,生成新的可执行程序。

合并符号表就是把不同文件的符号合并在一起,如果有相同的符号,只要一个(重定位),且地址是有意义的(比如函数声明的符号名,函数定义的符号名,后者才是有意义的)。有时候程序调试会报出无法解析的外部符号,一般就是链接除了问题。

        二.运行环境

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

  • 14
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 12
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

Ke vin

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

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

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

打赏作者

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

抵扣说明:

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

余额充值