从编译器角度来理解C++代码的编译和链接原理

本文详细阐述了Linux系统中C++代码的编译过程,包括预编译、编译、汇编和链接四个阶段。讨论了.o文件和可执行文件的格式组成,以及符号表在不同阶段的作用。在链接过程中,解释了如何解决符号引用和重定位,以及符号何时分配虚拟地址。最后,介绍了可执行文件加载到内存的过程。
摘要由CSDN通过智能技术生成

我们可以在linux系统下对下列代码是如何进行编译进行一个理解:

main.cpp

//引用sum.cpp文件里面定义的全局变量以及函数
extern int gdata;
int sum (int, int) ;
int data = 20;
int main ()
{
	int a = gdata;
	int b = data;
	int ret =sum (a, b);
	return o;
}

sum.cpp

int gdata = 10;
int sum(int a, int b)
{
	return a+b;
}

请添加图片描述
接下来我们将从以下几个问题展开:

  1. *.o文件的格式组成是什么样的?
  2. 可执行文件的组成格式是什么样子?
  3. 上图中步骤一和步骤二是做的什么事情?
  4. 符号表的输出里面的符号怎么理解?
  5. 符号什么时候分配虚拟地址?

预编译(.c -> .i):

  1. #开头的命令的预处理(除了#pragma lib和#pragma link)
  2. 将所有的“#define”删除,并且展开所有的宏定义。
  3. 注释的删除和替换
  4. 头文件的引入。
  5. 保留所有的#pragma编译器指令,因为编译器须要使用它们。
  6. 添加行号和文件名标识,以便于编译时编译器产生调试用的行号信息及用于编译时产生编译错误或警告时能够显示行号;

编译(.i -> .s):

词法分析;语法分析;语义分析;以及优化后生产相应的汇编代码文件

汇编(.s -> .o):

汇编分为两种x86和AT&T;将汇编代码转变成机器可以执行的指令,汇编后生成二进制可重定位的目标文件.o
我们可以通过objdump命令来查看.o.exe文件的相关信息。
例如,我们可以是使用objdump -t main.o来查看其中的符号表信息。
请添加图片描述
我们可以看到在main.o里面引用了外部文件的gdata变量和sum函数,在符号表中都是UND的,也就是(undefine);这就意味着汇编器生成符号的时候在main.cpp文件中使用到了但是未找到gdata和sum的定义,所以只能暂时存放在UND段中。

链接(.o -> a.out):

编译完成的所有.o文件+静态库文件进行链接

  1. 第一个步骤就是将所有.o文件段的合并,符号表合并后进行符号解析
  2. 第二个步骤就是符号的重定位(链接的核心)。

.o文件的格式组成:
elf文件头
.text
.data
.bss
.symbal
.section table

下面我们详解一下.o文件段的合并:

  1. 首先是所有.o文件段的合并, 也就是main.osum.o.text.data等段合并到一起。
  2. 其次是符号解析,可以理解为: 所有对符合引用,都要找到该符号定义的地方
    也就是链接器寻找main.o文件中UND的gdata和sum符号定义的地方,如果找遍了所有地方都没有找到,那么链接器就会报错:符号未定义!,或者是在多个地方都找到了相同的符号定义,那么也会报错:符号重定义!
    对于本例来说,这两个符号会在sum.o的.text和.data段找到符号的定义地方。
  3. 最后是符号的重定向给所有的符号分配虚拟地址,之后去代码段中给所有的符号重定向

符号什么时候分配虚拟地址?
链接的第一步符号解析完成后进行分配虚拟地址的。(编译过程符号是不分配虚拟地址的)

我们二进制可重定位目标文件和可执行文件最大的区别是什么呢?
可执行文件有program headers段。由两个load告诉系统运行这个程序的时候把哪些内容加载到内存中,加载的是代码段和数据段,由下图可以看出:
请添加图片描述

可执行文件加载的大概过程如下图:请添加图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值