C++笔记_01深入编译链接和运行

来源:互联网 发布:商城系统数据库设计 编辑:程序博客网 时间:2024/06/01 10:30

用任何语言写代码,无非产生两种东西,,,指令+数据

CPU的位数,指的是:一次性,能加以运算的最长的正数的宽度。   

ALU 算数逻辑单元的宽度

 

虚拟内存的大小与CPU的位数有关系  SIZE== 2^32 == 4G

 

0x0000 0000    ------  0x FFFF FFFF

 

0x00000000 -> 0x C000 0000   用户空间(低3G)

0x C0000 0000 -> 0x FFFF FFFF    内核空间(高1G)

0x0000 0000 -> 0x 0804 8000     128M的禁止访问区域

 

.text     代码段   存放指令

.data    数据段 存放数据  (已经初始化的数据)

.bss     数据段 存放数据  (未初始化或初始化为0的变量)占用虚拟地址空间

heap    堆

共享库    如果当前程序用到库中的函数

.stack    栈

命令行参数

环境变量

(以上是用户空间)

-----------(分界线)

(以下是内核空间)

ZONE_DMA         低16M      直接内存访问(加速内存和磁盘之间访问数据用的)

ZONE_NORMAL     中间892M    内核常用

ZONE_HIGHMEN     高128M     高端内存(主要在内核映射高于1G的物理内存)

 

内存布局以及相互之间的关系


.data?? 数据段,存放程序中已经初始化的变量

.bss?? 占用的是虚拟地址空间 层程序中未初始化偶初始化为0的变量

heap 存放进程中运行中被动态分配的内存段

stack 存放程序临时创建的局部变量

内核共享,,,用户空间独立

 

编译的过程

预编译 :  去掉注释以及#开头的预处理文件

编译: 代码的优化,汇总所有的符号

汇编: 根据特定平台转化成该平台特定的机器码,CPU使用汇编指令将代码生成二进制可重定位目标文件

生成二进制可重定位目标文件:  .obj   .o   内部存在符号表

数据产生符号,函数只产生函数名符号

重定位?  二进制目标语言重定位之后才可运行1

指把 程序的逻辑地址空间变换成内存中的实际物理地址空间的过程,也就是再装载时对目标城中指令和数据的修改过程。分为两种  动态、静态重定位。

 

虚拟内存:: 是计算机系统内存管理的一种技术。它使应用程序认为它拥有连续的可用内存(一个连续完整的地址空间),实际上它通常是被分隔成多个物理内存碎片,还有部分暂时存储在外部磁盘存储器上,在需要时进行数据交换。如, windows的虚拟内存,linux的交换空间等

 

http://baike.baidu.com/link?url=1dFbPEuytWnfia9BC78ysbOXUEshpbV_zehkQ4FTu4j1ssM2uQLHgcLKORhCSPbsgUh-LkJPAcuoWtjuAvo188nMRFltLrdosigp93hfSh-zZMETAfqiZRMUNhI7Zzjw

 

 

链接

  1.合并所有.obj文件的段,并调整段的段偏移和段长度,合并符号表进行符号解析  [仅分配内存地址]

  2.链接的核心。。  符号重定位

链接时 对所有.obj文件的glocal(全局)符号进行处理,local(局部)的符号不做任何处理

符号解析??  :: 所有obj符号表中对符号引用的地方都要找到该符号定义的地方

所有相同属性的段进行合并组织在一个界面上

 

可执行文件

???

 

C语言中强符合和若符号

初始化了的是强符号,包括初始化为0                                    

没初始化的是若符号

若同时出现了强符号和若符号,则选择强符号

多个若符号,则选择内存占用量最多的,但是随着编译器的不同它也不同

 

main.o结构

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

程序运行的过程

 

1.创建虚拟地址空间到物理内存的映射(创建内核地址映射结构体),创建目录和页表

2.加载代码段和数据段

3.把可执行文件的入口地址写到CPU的PC寄存器里面

 

 

 

 

 

 

 

 

mmap 函数    用来映射磁盘《深入理解计算机第九章》

可执行文件结构:

 

比.obj(可重定位二进制目标文件)多一个在ELF Header 下面多一个programheaders(程序启动入口)

 

 

???为什么每个程序入口地址都是0x80482e0

符号地址都一样?

 

0x80482e0地址是.text的地址(代码段的开始)也是_start()的地址。在_start()中又会调用_libc_start_main(),=》程序初始化

 

*UDN* ???对符号的引用

.test 是对符号的定义,在链接的第一阶段,所有的.obj文件的段都会进行合并调整段的大小以及起始地址的偏移量,然后合并符号表进行符号解析,让所有符号引用的地方都要定位到符号的定义处,具有唯一性,定位好之后分配内存的虚拟地址;第二步进行符号的重定位,