编译链接过程

  • 编译链接

.c/.cpp                 

预编译(生产.i文件)                                                              编译(生产 .s文件,即汇编文件)                        

操作指令:gcc –E main.c –o main.i                                        操作指令:gcc –c main.s –o main.o                            

删除#define文本替换                                                               词法分析                       

处理所有条件预编译指令,如#if #endif #elif                            语法分析

递归展开#include                                                                     语义分析

删除注释                                                                                   代码优化

添加行号和文件标识                                                                 生成汇编指令

保留所有的#pragma编译器指令

                                                                  进程

汇编(生产.o文件,二进制可重定位文件)                              链接.exe(生产可执行程序)

操作指令:gcc –c main.s –o main.o                                         操作指令:gcc –o main main.s

翻译指令(将汇编代码转变成机器可以执行的指令)               合并段和符号表  

                                                                                                  符号解析

                                                                                                  分配地址和空间

                                                                                                  符号重定位

 

  1. 所有的数据都会生产符号,指令只有函数名生产符号
  2. 程序运行在:(32位系统  2^32  4G虚拟地址空间)

    4G虚拟地址空间:

  • 虚拟地址空间

任何进程都会产生它们的虚拟地址空间,一下是LINUX32位操作系统产生的虚拟地址空间图

 

  1. 虚拟地址空间分为两大块,一个是用户空间,一个是内核空间。用户空间占3G的大小,并且它是每个进程独有的,它的开头128M存放的是我们无法访问的地方。
  2. .text段:它也叫指令段,顾名思义,它存放的是指令代码,在程序中,我们把局部变量定义(局部变量的定义是指令而不是数据)还有一些操作指令都存放在.text中。它的属性是可执行可读不可写。
  3. .data段:数据段,里面存放的是初始化不为0 的静态局部变量和全局变量。属性是可读可写不可执行。
  4. .bss段:数据段,里面存放的是未初始化或者初始化为0的全局变量和静态局部变量。属性是可读可写不可执行,在bss段中的数据默认都会被修改为0.
  5. 堆:堆内存是我们在c语言中用malloc申请或者在c++中用new来申请的一端可能不连续的内存,堆是由低地址向高地址申请的。
  6. 栈:栈中存放我们的局部变量,特性是先进后出,并且它是由系统自动开辟以及释放。并且内存是连续的。
  7. 命令行参数:main函数的参数列表。Argc参数个数  argv参数内容  envp环境变量
  8. 环境变量:即envp的值
  9. 最下边是内核空间

 

  • ELF文件

1、ELF文件:在计算机科学中,是一种用于二进制文件、可执行文件、目标代码、共享库和核心转储格式文件。ELF由4部分组成,分别是ELF头(ELF header)、程序表头(Program header table)、节(Section)和节头表(Section header table)。

 

在elf文件结构中,有一个字符串表.strtab,里面存放的是elf文件中各个段的名字以及变量名等字符串,字符串表中记录了这些字符串以及对应的下标、需要用到这些字符串时,直接用偏移下标去取就行了。段表中存放的段的名字这一项,就是存的.strtab中对应字符串的偏移。

 

2、符号:所有数据都会生产符号,指令只有函数名会生产符号。

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

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

 

  • 链接
  1. 链接有以下几个部分要做:
  1. 合并段表:将多个二进制可重定位文件中的段信息合放到一个文件中
  2. 调整段偏移:段表经过合并之后大小发生了变化,所以地址需要适当的偏移
  3. 合并符号表:将多个二进制可重定位文件中的符号整合到一个文件中
  4. 完成符号的重定位:连接器把每个符号定义与一个虚拟地址联系起来,然后修改所有对这些符号的引用,使得他们指向这个存储位置,从而重定位这些节。

 

  • 按照属性划分不同的段放在同一页,运行时按照LOAD页信息将段按照页读入到虚拟地址空间。

 

 

 

 

 

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值