【UNIX】从一个可执行文件的生成到进程在内存中分布 (下)/进程的内存分布
2015-01-04 00:05
239 查看
从一个可执行文件的生成到进程在内存中分布 (下)
进程的内存分布
程序运行开始,由系统为进程地址空间中的text/data/bss段进行映射,由系统的缺页异常处理程序按需将磁盘上程序文件中的真正代码、数据写入进程。此外,bss区域中的所有变量都会被清零。
当一个可执行文件静态的存储在物理内存空间时,我们没考虑太多关于可执行文件存储在物理内存中是怎么分布存储的以及相关的地址信息,这些被静态编译的文件都是以固定的格式存放于不同的存储介质中,只有相对地址的概念,当我们在编译、链接的时候,编译器会根据具体的链接脚本,把可执行文件的各个目标文件模块的相关信息以段的方式有效整合的链接到对应的内存空间中,这里我们就要考虑到对于CPU来说,要处理相关的指令是根据指令的地址信息来取指的。还有要注意的是(一个程序的链接地址就是虚拟地址,而运行地址就是物理地址,这就要涉及到物理地址和虚拟地址的转换问题,它是通过MMU内存管理单元来实现的)
当涉及到地址相关的操作,我们就应该弄清楚进程是在内存空间怎么分布的问题以及一个进程的一般有哪些部分
![](https://img-blog.csdn.net/20150104211835402?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0pfS2Fubw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
![](https://img-blog.csdn.net/20150104211510152?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvQ0pfS2Fubw==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/Center)
bss段:
BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文BlockStarted by Symbol的简称。BSS段属于静态内存分配。
data段:
数据段(datasegment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
text段:
代码段(codesegment/textsegment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
rodata段:
存放C中的字符串和#define定义的常量
heap堆:
堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
stack栈:
是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
常量段:
常量段一般包含编译器产生的数据(与只读段包含用户定义的只读数据不同)。比如说由一个语句a=2+3编译器把2+3编译期就算出5,存成常量5在常量段中
特别注意:
1)text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;
2)bss段不在可执行文件中,由系统初始化。
3)bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小,具体体现为一个占位符。
4).bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);
而.data却需要占用,其内容由程序初始化
进程的内存分布
程序运行开始,由系统为进程地址空间中的text/data/bss段进行映射,由系统的缺页异常处理程序按需将磁盘上程序文件中的真正代码、数据写入进程。此外,bss区域中的所有变量都会被清零。
当一个可执行文件静态的存储在物理内存空间时,我们没考虑太多关于可执行文件存储在物理内存中是怎么分布存储的以及相关的地址信息,这些被静态编译的文件都是以固定的格式存放于不同的存储介质中,只有相对地址的概念,当我们在编译、链接的时候,编译器会根据具体的链接脚本,把可执行文件的各个目标文件模块的相关信息以段的方式有效整合的链接到对应的内存空间中,这里我们就要考虑到对于CPU来说,要处理相关的指令是根据指令的地址信息来取指的。还有要注意的是(一个程序的链接地址就是虚拟地址,而运行地址就是物理地址,这就要涉及到物理地址和虚拟地址的转换问题,它是通过MMU内存管理单元来实现的)
当涉及到地址相关的操作,我们就应该弄清楚进程是在内存空间怎么分布的问题以及一个进程的一般有哪些部分
bss段:
BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。BSS是英文BlockStarted by Symbol的简称。BSS段属于静态内存分配。
data段:
数据段(datasegment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。
text段:
代码段(codesegment/textsegment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。
rodata段:
存放C中的字符串和#define定义的常量
heap堆:
堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)
stack栈:
是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。
常量段:
常量段一般包含编译器产生的数据(与只读段包含用户定义的只读数据不同)。比如说由一个语句a=2+3编译器把2+3编译期就算出5,存成常量5在常量段中
特别注意:
1)text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;
2)bss段不在可执行文件中,由系统初始化。
3)bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小,具体体现为一个占位符。
4).bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);
而.data却需要占用,其内容由程序初始化
相关文章推荐
- 【UNIX】从一个可执行文件的生成到进程在内存中分布 (上)/可执行文件的生成
- 一个可执行文件的生成过程到进程在内存中的分布
- 进程,可执行文件和内存的关系
- 可执行文件及linux进程内存
- c语言从一个源代码文件到生成可执行文件的过程
- 进程地址空间分布和可执行文件分布
- UNIX环境高级编程学习之第十五章进程间通信 - 两个进程通过映射普通文件实现共享内存通信
- 根据进程查找该进行的执行位置和完整执行指令和检查文件开始生成时间
- C程序可执行文件和运行时的内存分布
- 【C语言】【unix c】使用mmap将文件映射到进程的虚拟地址空间,然后对内存的操作直接反应到文件中
- Linux 可执行文件与进程内存结构, Linux 进程内存加载
- Unix高级编程:malloc内存管理、缓冲机制、mmap内存映射到进程、系统调用文件操作
- 进程地址空间分布和可执行文件分布
- Linux\Unix IPC进程通信实例分析(一):共享内存通信---文件映射mmap方式
- linux内核情景分析 UNIX环境高级编程 {进程 文件 内存}
- 生成UNIX可执行文件
- 如何获取linux进程的执行文件路径
- [j2se]如何生成自动执行的jar文件(自己收藏)
- UNIX 下让 Oracle 定时执行 *.sql 文件
- ASP.NET中上传并读取Excel文件数据,附后生成EXCEL及杀掉EXCEL进程。