编译链接原理

虚拟地址空间

       32位计算机,每个程序都有4G的虚拟地址空间。首先虚拟地址空间分为两大块,一个是用户空间,一个是内核空间。用户空间占3G的大小,并且它是每个进程所独有的,它的开头128M存放的是我们无法访问的地方。

  • .text段:它也叫指令段,顾名思义,它存放的是指令代码,在程序中,我们把局部变量定义(局部变量的定义是指令而不是数据)还有一些操作指令都存放在.text中。它的属性是可执行可读不可写。
  • .data段:数据段,里面存放的是初始化不为0的静态局部变量和全局变量。属性是可读可写不可执行。注意:在data段上面有一个rodata段(rodata段的位置在.o文件时去观察它是在.bss段的下方),它的属性是只可读。所以当我们这样定义字符串时:char *p = “hello world”; *p = ‘a’;会报错的原因就是这里的”hello world”在rodata段存放,它只可读,不可修改。
  • .bss段:数据段,里面存放的是未初始化或者初始化为0的全局变量和静态局部变量。属性是可读可写不可执行,在bss段中的数据默认都会被修改为0。
  • 堆:堆内存是我们在c语言中用malloc申请或者在c++中用new来申请的一端可能不连续的内存,堆是由低地址向高地址申请的。
  • 栈:栈中存放我们的局部变量,特性是先进后出,并且它是由系统自动开辟以及释放。并且内存是连续的。
  • 命令行参数:main函数的参数列表。argc 参数个数  argv 参数内容 envp 环境变量
  • 环境变量:即envp的值
  • 最下边是内核空间

编译(生成二进制可重定位文件)

1、预编译(生成 .i 文件)

操作命令:gcc -E main.c -o main.i
    具体内容:
   (1)宏定义指令
   (2)条件编译
   (3)头文件包含指令
   (4)特殊符号处理
常见问题:
     不能在头文件中定义全局变量,因为在头文件中定义全局变量将会使所有包含该头文件的文件存在该段代码,也就是说这些文件将定义一个相同的全局变量,这样将不可避免的造成冲突 

2、编译(生成 .s 文件,即汇编文件)
操作命令:gcc -S main.i -o main.s
    具体内容:编译环节是指对源代码进行语法分析,并优化产生对应的汇编代码的过程
(1)    生成符号
(2)    生成汇编指令

3、汇编(生成 .o 文件,即二进制可重定位文件)
操作命令:gcc -c main.s -o main.o
具体内容:将汇编语言翻译成机器语言(二进制)代码

注意:

  • .bss段在二进制可重定位文件中不占内存,达到了节省空间的目的(问题:数据如何标识?)。

       因为.bss段中的数据都是没有初始化或初始化为0的数据,所以每个数的值都为0,没必要每个都存储,只需要标识其存在即可。每个数据都会生符号,.bss段的大小只是说明有多少个数据(弱符号不计入其中),并不实际存储,而实际的数据产生的符号在符号表中。这样就解决了数据的标识问题。

  • 强符号和弱符号

强符号:初始化了的非静态数据

弱符号:没有初始化的非静态数据

弱符号不往数据段存储(指的是不参与.bss段对数据个数的计算),只会产生一个/*COM*标志

链接(生成可执行程序)

操作命令:gcc -o main main.s

具体内容:将有关的目标文件彼此链接,也即将在一个文件中引用的符号同该符号在另外一个文件中的定义链接起来,是的所有的这些文件成为一个能够让操作系统装入执行的统一整体,可分为动态链接和静态链接
链接有以下几个部分要做:
1、 合并段表:将多个二进制可重定位文件中的段信息整合放到一个文件中
2、 调整段偏移:段表经过合并之后大小发生了变化,所以地址需要适当的偏移
3、 合并符号表:将多个二进制可重定位文件中的符号整合到一个文件中
4、 完成符号的重定位:连接器把每个符号定义与一个虚拟地址联系起来,然后修改所有对这些符号的引用,使得它们指向这个存储位置,从而重定位这些节。

运行:

按照不同段的属性相同的不同的段划分到同一页装入虚拟地址空间

附:

32位虚拟地址空间是多大?为啥?
4G,32位指的是地址总线的条数 32条,2^32 = 4G


 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值