linux目标文件

一个简单的程序被编译成目标文件后的结构如下:

从图可以看出,已初始化的全局变量和局部静态变量保存在 .data段中,未初始化的全局变量和未初始化的局部静态变量保存在 .bss段中。

目标文件各个段在文件中的布局如下:

各个段介绍:

init段:

  程序初始化入口代码,在main() 之前运行。

bss段:

  BSS段属于静态内存分配。通常是指用来存放程序中未初始化的全局变量和未初始化的局部静态变量。未初始化的全局变量和未初始化的局部静态变量默认值是0,本来这些变量也可以放到data段的,但是因为他们都是0,所以为他们在data段分配空间并且存放数据0是没有必要的。

程序在运行时,才会给BSS段里面的变量分配内存空间。

在目标文件(*.o)和可执行文件中,BSS段只是为未初始化的全局变量和未初始化的局部静态变量预留位置而已,它并没有内容,所以它不占据空间。

section table中保存了BSS段(未初始化的全局变量和未初始化的局部静态变量)内存空间大小总和。 (objdump -h *.o 命令可以看到)

data段:

  数据段(datasegment)通常是指用来存放程序中已初始化的全局变量和已初始化的静态变量的一块内存区域。数据段属于静态内存分配。

text段:

  代码段(codesegment/textsegment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

rodata段:

  存放的是只读数据,比如字符串常量,全局const变量 和 #define定义的常量。例如: char*p="123456", "123456"就存放在rodata段中。

strtab段:

  存储的是变量名,函数名等。例如: char* szPath="/root",void func()  变量名szPath 和函数名func 存储在strtab段里。

shstrtab段:

  bss,text,data等段名也存储在这里。

rel.text段:

  针对 text段的重定位表,还有 rel.data(针对data段的重定位表)

heap堆:

  堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

stack栈:

  是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

验证BSS内存空间

程序1:

int ar[30000];
void main()
{

......

}

程序2:

int ar[300000] =  {1, 2, 3, 4, 5, 6 };
void main()
{

......

}

结论是:程序2编译之后所得的.exe文件比程序1的要大得多。 为什么?

区别很明显,一个位于.bss段,而另一个位于.data段,两者的区别在于:

l          全局的未初始化变量存在于.bss段中,具体体现为一个占位符;全局的已初始化变量存于.data段中;

l          而函数内的自动变量都在栈上分配空间。

l          .bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);

l          而.data却需要占用,其内容由程序初始化,因此造成了上述情况。

注意:

1. bss段(未手动初始化的数据)并不给该段的数据分配空间. 程序运行后,系统分配内存空间并由系统初始化,默认内存空间的值都为0.  section table中保存了BSS段(未初始化的全局变量和未初始化的局部静态变量)内存空间大小总和,所以程序运行后,系统知道该分配多少内存给BSS段。

2. data(已手动初始化的数据)段则为数据分配空间,数据保存在目标文件中。

这里有个疑问: data段是变量的内存空间,那是如何区分哪几个字节是变量a的? 哪几个字节是变量b的? 因为变量a,b的内存空间是在一起的,如果你不告诉他们的类型,我们的确是不知道变量a有几个字节,变量b有几个字节。

那么哪里保存了 变量a,b的类型了?  查资料发现,text代码段中调用a的汇编代码,是会告诉我们变量a的类型的,这样我们就知道读取哪几个字节的值了。 程序运行起来后,BSS段中变量内存数据读取原理类似。

linux 目标文件 bss,data,text,rodata,堆,栈***的更多相关文章

  1. .bss,.data,.text,.rodata

    那天工作时候发现build的时候发现问题, 问题内容是:.text的空间太小了. 我一直以为写代码,就真是弄懂代码怎么写,式样书怎么写,或者弄懂代码的问题所在, 没有想到在build的时候出现问题.结 ...

  2. 汇编中bss,data,text,rodata,heap,stack,意义

    bss段: BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文BlockStarted by Symbol的简称.BSS段属于静态内存分配. data ...

  3. linux 目标文件调试

    前言如果普通编程不需要了解这些东西,如果想精确控制你的对象文件的格式或者你想查看一下文件对象里的内容以便作出某种判断,刚你可以看一下下面的工具:objdump, nm, ar.当然,本文不可能非常详细 ...

  4. BSS, DATA, TEXT, HEAP, STACK

    BSS, block start segment, static memory, to store the global data which are not initialized. DATA, d ...

  5. LINUX下目标文件的BSS段、数据段、代码段

    http://blog.chinaunix.net/uid-27018250-id-3867588.html bss 未初始化的全局数据 data 已经初始化的全局数据 text 代码段,机器指令 r ...

  6. linux c 链接详解1-多目标文件链接

    1. 多目标文件的链接 摘自:linux c编程一站式学习 http://learn.akae.cn/media/index.html 可以学会在linux下将多个c语言文件一起编译. 现在我们把例  ...

  7. text bss data的区别

    BSS段 在采用段式内存管理的架构中,BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS ...

  8. Linux下目标文件分析

    文章来源:华清远见嵌入式学院,原文地址:http://www.embedu.org/Column/Column699.htm 作者:冯老师,华清远见嵌入式学院讲师. 1. 程序源码如下: 2.命令 g ...

  9. Linux源码与编译出的目标文件汇编代码的一致性问题

    start_kernel是内核启动时比较重要的一个函数,然而我发现一个问题,我编译出来的目标文件中的汇编代码与C源码并不完全对应,这是怎么一回事呢? asmlinkage void __init st ...

随机推荐

  1. java中TreeMap集合的常用方法

    实现Map集合的方法这里就不在讲了 https://www.cnblogs.com/xiaostudy/p/9510763.html public Map.Entry<K,V> ceili ...

  2. DevExpress的GridControl选择一行,不显示单元格焦点的设置

    grid控件默认选择一行时,focused的cell并不是蓝色的,而是白色的 要想实现一次选择一行全都是蓝色的只要改一个属性就可以了 this.gridView1.OptionsSelection.E ...

  3. yii2:多条件多where条件下碰到between时,between语句如何处理呢?

    yii2:多条件多where条件下碰到between时,between语句如何处理呢? 我有一张表:id,name,telphone,ticket_no,status,create_time等字段, ...

  4. Android TextView 设置滚动条(纯xml)

    <ScrollView android:id="@+is/scrollView_id" android:layout_width="fill_parent" ...

  5. 三十三 Python分布式爬虫打造搜索引擎Scrapy精讲—数据收集(Stats Collection)

    Scrapy提供了方便的收集数据的机制.数据以key/value方式存储,值大多是计数值. 该机制叫做数据收集器(Stats Collector),可以通过 Crawler API 的属性 stats ...

  6. 玩转maven

    Maven是一个项目管理工具,它包含了一个项目对象模型 (Project Object Model),一组标准集合,一个项目生命周期(Project Lifecycle),一个依赖管理系统(Depen ...

  7. HBase Cassandra比较

    转自:http://itindex.net/detail/22338-cassandra-hbase-%E8%AE%BE%E8%AE%A1     Cassandra HBase 一致性 Quorum ...

  8. python 在头文件添加 #include \"stdafx.h\"\r\n

    import osimport shutil#-*- coding:cp936 -*-import codecsfrom sys import argv def replace_all_files(p ...

  9. 【PAT-L2-020】功夫传人

    链接:https://www.patest.cn/contests/gplt/L2-020 一门武功能否传承久远并被发扬光大,是要看缘分的.一般来说,师傅传授给徒弟的武功总要打个折扣,于是越往后传,弟 ...

  10. mysql int(3)与int(11)的区别

    总结,int(M) zerofill,加上zerofill后M才表现出有点点效果,比如 int(3) zerofill,你插入到数据库里的是10,则实际插入为010,也就是在前面补充加了一个0.如果i ...