从编译器角度来理解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.头文件的引入。4.保留所有的#pragma编译器指令,因为编译器须要使用它们。
编译(.i -> .s):词法分析;语法分析;语义分析;以及优化后生产相应的汇编代码文件。
汇编(.s -> .o):汇编分为两种x86和AT&T;将汇编代码转变成机器可以执行的指令
,生成二进制可重定位的目标文件。
链接(.o -> a.out):编译完成的所有.o文件+静态库文件进行链接,第一个步骤就是将所有.o文件段的合并,符号表合并后进行符号解析;第二个步骤就是符号的重定位(链接的核心)。
.o文件的格式组成:
elf文件头
.text
.data
.bss
.symbal
.section table

下面我们详解一下.o文件段的合并:
就是当我们main.o sum.o合并的时候各个段就要进行合并了.text <=> .text .bss <=> .bss .data<=> .data等等之间进行合并
符号解析:所有对符号的引用,都要找到该符号定义的地方。
符号解析成功以后!!!!就要给所有的符号分配虚拟地址。(即符号的重定向)
符号什么时候分配虚拟地址:
链接的第一步符号解析完成后进行分配虚拟地址的。(编译过程符号是不分配虚拟地址的)
我们二进制可重定位目标文件和可执行文件最大的区别是什么呢?
可执行文件有program headers段。由两个load告诉系统运行这个程序的时候把哪些内容加载到内存中,加载的是代码段和数据段,由下图可以看出:
在这里插入图片描述
可执行文件加载的大概过程如下图:
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值