PS:http://stackoverflow.com/questions/16557677/difference-between-data-section-and-the-bss-section-in-c

The .bss section is guaranteed to be all zeros when the program is loaded into memory. So any global data that is uninitialized, or initialized to zero is placed in the .bss section. For example:

static int g_myGlobal = 0;     // <--- in .bss section

The nice part about this is, the .bss section data doesn't have to be included in the ELF file on disk (ie. there isn't a whole region of zeros in the file for the .bss section). Instead, the loader knows from the section headers how much to allocate for the .bss section, and simply zero it out before handing control over to your program.

Notice the readelf output:

[ 3] .data PROGBITS 00000000 000110 000000 00 WA 0 0 4
[ 4] .bss NOBITS 00000000 000110 000000 00 WA 0 0 4

.data is marked as PROGBITS. That means there are "bits" of program data in the ELF file that the loader needs to read out into memory for you. .bss on the other hand is marked NOBITS, meaning there's nothing in the file that needs to be read into memory as part of the load.


Example:

// bss.c
static int g_myGlobal = 0; int main(int argc, char** argv)
{
return 0;
}

Compile it with $ gcc -m32 -Xlinker -Map=bss.map -o bss bss.c

Look at the section headers with $ readelf -S bss

Section Headers:
[Nr] Name Type Addr Off Size ES Flg Lk Inf Al
[ 0] NULL 00000000 000000 000000 00 0 0 0
:
[13] .text PROGBITS 080482d0 0002d0 000174 00 AX 0 0 16
:
[24] .data PROGBITS 0804964c 00064c 000004 00 WA 0 0 4
[25] .bss NOBITS 08049650 000650 000008 00 WA 0 0 4
:

Now we look for our variable in the symbol table: $ readelf -s bss | grep g_myGlobal

37: 08049654     4 OBJECT  LOCAL  DEFAULT   25 g_myGlobal

Note that g_myGlobal is shown to be a part of section 25. If we look back in the section headers, we see that 25 is .bss.


To answer your real question:

Here in the above program I dont have any un-intialised data but the BSS has occupied 8 bytes. Why does it occupy 8 bytes ?

Continuing with my example, we look for any symbol in section 25:

$ readelf -s bss | grep 25
9: 0804825c 0 SECTION LOCAL DEFAULT 9
25: 08049650 0 SECTION LOCAL DEFAULT 25
32: 08049650 1 OBJECT LOCAL DEFAULT 25 completed.5745
37: 08049654 4 OBJECT LOCAL DEFAULT 25 g_myGlobal

The third column is the size. We see our expected 4-byte g_myGlobal, and this 1-byte completed.5745. This is probably a function-static variable from somewhere in the C runtime initialization - remember, a lot of "stuff" happens before main() is ever called.

4+1=5 bytes. However, if we look back at the .bss section header, we see the last column Al is 4. That is the section alignment, meaning this section, when loaded, will always be a multiple of 4 bytes. The next multiple up from 5 is 8, and that's why the .bss section is 8 bytes.


Additionally We can look at the map file generated by the linker to see what object files got placed where in the final output.

.bss            0x0000000008049650        0x8
*(.dynbss)
.dynbss 0x0000000000000000 0x0 /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib/crt1.o
*(.bss .bss.* .gnu.linkonce.b.*)
.bss 0x0000000008049650 0x0 /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib/crt1.o
.bss 0x0000000008049650 0x0 /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib/crti.o
.bss 0x0000000008049650 0x1 /usr/lib/gcc/x86_64-redhat-linux/4.7.2/32/crtbegin.o
.bss 0x0000000008049654 0x4 /tmp/ccKF6q1g.o
.bss 0x0000000008049658 0x0 /usr/lib/libc_nonshared.a(elf-init.oS)
.bss 0x0000000008049658 0x0 /usr/lib/gcc/x86_64-redhat-linux/4.7.2/32/crtend.o
.bss 0x0000000008049658 0x0 /usr/lib/gcc/x86_64-redhat-linux/4.7.2/../../../../lib/crtn.o

Again, the third column is the size.

We see 4 bytes of .bss came from /tmp/ccKF6q1g.o. In this trivial example, we know that is the temporary object file from the compilation of our bss.c file. The other 1 byte came from crtbegin.o, which is part of the C runtime.


Finally, since we know that this 1 byte mystery bss variable is from crtbegin.o, and it's named completed.xxxx, it's real name is completed and it's probably a static inside some function. Looking at crtstuff.c line 362 we find the culprit: a static _Bool completed inside of __do_global_dtors_aux().

[转] .bss段和.data段的区别的更多相关文章

  1. bss段和data段的区别

    一般情况下,一个程序本质上都是由 bss段.data段.text段三个组成的——本概念是当前的计算机程序设计中是很重要的一个基本概念.而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大 ...

  2. [转帖]浅谈程序中的text段、data段和bss段

    作者:百问科技链接:https://zhuanlan.zhihu.com/p/28659560来源:知乎著作权归作者所有.商业转载请联系作者获得授权,非商业转载请注明出处. 一般情况,一个程序本质上都 ...

  3. (深入理解计算机系统) bss段,data段、text段、堆(heap)和栈(stack)

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

  4. 【转】(深入理解计算机系统) bss段,data段、text段、堆(heap)和栈(stack)

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

  5. Linux中的段管理,bss段,data段,

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

  6. [转] bss段、data段、text段

    1.前言 一个程序本质上都是由 BSS 段.DATA段.TEXT段三个组成的. 本文主要分编译时和运行时分别对 对data段 bss段 text段 堆 栈作一简要说明 2. 程序编译时概念说明 程序与 ...

  7. Text段、Data段和BSS段

    不同的compiler在编译的过程中对于存储的分配可能略有不同,但基本结构大致相同. 大体上可分为三段:Text段.Data段和BSS段. text段用于存放代码,通常情况下在内存中被映射为只读,但d ...

  8. 代码中函数、变量、常量 / bss段、data段、text段 /sct文件、.map文件的关系[实例分析arm代码(mdk)]

    函数代码://demo.c #include<stdio.h> #include<stdlib.h> , global2 = , global3 = ; void functi ...

  9. Linux段管理,BSS段,data段,.rodata段,text段

    近期在解决一个编译问题时,一直在考虑一个问题,那就是Linux下可执行程序执行时内存是什么状态,是依照什么方式分配内存并执行的.查看了一下资料.就此总结一下,众所周知.linux下内存管理是通过虚存管 ...

随机推荐

  1. 三、singleton(单例化)一个对象的几种方法

    方案一:私有化构造器,通过static final域 @Test public void test13() { A215 a=A215.a; A215 b=A215.a; System.out.pri ...

  2. hibernate_validator_02

    三种不通的注解 1. 字段级(field level) 约束 package com.mycompany; import javax.validation.constraints.NotNull; p ...

  3. 【BZOJ1010】玩具装箱

    Description P教授要去看奥运,但是他舍不下他的玩具,于是他决定把所有的玩具运到北京.他使用自己的压缩器进行压缩,其可以将任意物品变成一堆,再放到一种特殊的一维容器中.P教授有编号为1... ...

  4. 【USACO 2.2.2】集合

    [题目描述] 对于从1到N (1 <= N <= 39) 的连续整数集合,能划分成两个子集合,且保证每个集合的数字和是相等的.举个例子,如果N=3,对于{1,2,3}能划分成两个子集合,每 ...

  5. 用 javascript 判断 IE 版本号

    原文地址: http://julying.com/blog/determine-the-version-number-of-ie-with-javascript/ var _IE = (functio ...

  6. How to Enable or Disable a cell in DataGridview Row ?

    Following link http://msdn.microsoft.com/en-us/library/ms171619.aspxhttp://windowsclient.net/blogs/f ...

  7. 解决SQL Server Management Studio Express不支持更新全文目录的方法

    微软的说法:https://msdn.microsoft.com/zh-cn/library/ms365247.aspx 可以用命令创建: A.创建唯一索引.全文目录和全文索引 以下示例对 Adven ...

  8. Jssdk微信分享

    <?php require_once "jssdk.php"; $jssdk = new JSSDK("yourAppID", "yourApp ...

  9. [Python笔记]第十一篇:面向对象

    以上就是本节对于面向对象初级知识的介绍,总结如下: 面向对象是一种编程方式,此编程方式的实现是基于对 类 和 对象 的使用 类 是一个模板,模板中包装了多个“函数”供使用 对象,根据模板创建的实例(即 ...

  10. .net FrameWork4.0安装未成功

    安装了一上午的.net framework 4.0,各种失败,查了好多答案,各种不靠谱,最后终于找到答案了 和Windows Update有关系,给目录名重命名一下再次安装,即安装成功了! 下载地址: ...