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

关于text段、data段和bss段 根据APUE,程序分为下面的段:.text, data (initialized), bss, stack, heap。 data/bss/text: text段在内存中被映射为只读,但.data和.bss是可写的。 bss是英文Block Started by Symbol的简称,通常是指用来存放程序中未初始化的全局变量的一块内存区域,在程序载入时由内核清0。BSS段属于静态内存分配。它的 阅读详情

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

关于BSS段的大小 2

1. BSS段中的内容 2

2.BSS段在加载运行前的处理 3

3.BSS段的作用 3

4. 代码优化对BSS段的影响 3

5.Linux 下查看段属性的指令: 4

BSS大小实验 4

清除BSS段的一般做法 6

link脚本一般包含类似语句: 6

 

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

一个程序本质上都是由bss段、data段、text段三个组成的。

bss段:

bss段属于静态内存分配。 bss是英文Block Started by Symbol的简称。

 BSS段通常是指用来存放程序中未初始化的全局变量和静态变量的一块内存区域。特点是可读写的,在程序执行之前BSS段会自动清0,所以,未初始的全局变量在程序执行之前已经成0了。

特点是:可读写的,

data段:

数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。

数据段属于静态内存分配。

text段:

代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。

这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读(某些架构也允许代码段为可写,即允许修改程序)。

在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

堆(heap):

堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。

当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);

当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)。

栈(stack):

栈又称堆栈,是用户存放程序临时创建的局部变量,

也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。

除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。

由于栈的先进先出(FIFO)特点,所以栈特别方便用来保存/恢复调用现场。

从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

 

 

 

 

关于BSS段的大小

BSS段在执行文件中时候不占磁盘空间,要运行的时候才分配空间并清0.

历史原因

而很多时候,数据段里的全局变量都是0(或者没有初始值),那么存储这么多的0到目标文件(可执行)里其实是没有必要的。所以为了节约空间,在生成目标文件的时候,就把没有初始值(实际就是0)的数据段里的变量都放到BSS段里,这样目标文件就不需要那么大的体积里(节约磁盘空间)。只有当目标文件被载入(运行)的时候,加载器负责把BSS段清零(一个循环就可以搞定)。 之后,这个规则慢慢的成为一个标准配置,大多数编译器也就都支持了BSS段。

  1. BSS段中的内容

先明确 BSS 段“存放”的是未初始化的全局变量与局部静态变量,此处指的存放是指为其预留空间(占位符)。但BSS段在磁盘上不是真的占用变量大小的空间,它仅是在该段中记录了所有未初始化全局变量与局部静态变量的大小总和,至于每个变量的大小则存储在符号表的size属性中。即:

BSS段内容:无内容,它将在段表中占一个段描述符,该段描述符的size属性将记录未初始化的全局变量与局部静态变量的大小总和每个未初始化全局对象与静态对象的大小:存储在符号表的 size 属性中

(上述说法求证于C++牛人“蓝色”,表感谢。。。)

注:段表描述了ELF各个段的信息,比如每个段的段名,长度,在文件中的偏移等。ELF文件的段结构就是由段表决定的。

注:段表的结构是一个以“Elf32_shdr”结构体为元素的数组,数组元素个人等于段的数目,每一个结构体对应一个段。将这个结构体称为段描述符。而BSS则仅在段表中占用一个段描述符。但是在实际的ELF文件中不存在该段。

2.BSS段在加载运行前的处理

当可执行文件加载运行前,会为BSS段中的变量分配足够的空间并全部自动清理(因此,才有未初始化的全局变量的值为0的说法)。

3.BSS段的作用

BSS段主要是为了节省可执行文件在磁盘上所占的空间,其仅仅记录变量所需的大小。对未初始化的大型数组的节省效率比较明显。举例如下:

1.static int a[10000];  

2.int main()  

3.{  

4.     //...  

5.}  

在上述程序中,若不存在 BSS 段,则可执行文件将开辟一个 10000 * sizeof(int) 大小的空间,并全部存储为0,int 为4字节的情况下,该变量将在磁盘上占用39KB的空间。但是此时若是存在BSS 段,则在可执行文件中,将只是记录现在的BSS段总大小为40000即可,而无需真正的占据39KB的空间

该可执行文件在执行前将重新开辟39KB的空间,并自动初始化为0

4. 代码优化对BSS段的影响

全局变量与静态变量没有初始化或初始化值为0时,都会放在.bss段。初始化为非0值,则放在.data段。

 

考虑以下两个静态变量分别存储在哪个段中:

  1. static int x1 = 1;  
  2. static int x2 = 0;  

很明显可以看出,X1将被发在.data段中。令人意外的是 X2 将被放置在 .bss 段中,因为 x2 的值为0,被认为是未初始化的,因此将会被放在 .bss 段中以节省磁盘空间。

5.Linux 下查看段属性的指令:

用readelf -s 或 objdump -t 查看符号表用readelf -S 或 objdump -h 查看段表

 牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。

在采用段式内存管理的架构中(比如intel的80x86系统),bss段通常是指用来存放程序中未初始化的全局变量的一块内存区域,

 一般在初始化时bss段部分将会清零。bss段属于静态内存分配,即程序一开始就将其清零了。

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

BSS大小实验

比如,在C语言之类的程序编译完成之后,

  1. 已初始化的全局变量保存在.data段中,
  2. 未初始化的全局变量保存在.bss段中。

 

text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;而bss段不在可执行文件中,由系统初始化。

 

【例】

两个小程序如下:

程序1:

int ar[30000];

void main()

{

......

}

程序2:

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

void main()

{

......

}

发现程序2编译之后所得的.exe文件比程序1的要大得多。

 

当下甚为不解,于是手工编译了一下,并使用了/FAs编译选项来查看了一下其各自的.asm,

发现在程序1.asm中ar的定义如下:

_BSS SEGMENT

?ar@@3PAHA DD 0493e0H DUP(?);ar

_BSS ENDS

而在程序2.asm中,ar被定义为:

_DATA SEGMENT

?ar@@3PAHA DD 01H;ar

DD 02H

DD 03H

ORG$+1199988

_DATA ENDS

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

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

全局的已初始化变量存于.data段中;

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

 

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

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

bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小;

bss段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段后面。

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

data段包含经过初始化的全局变量以及它们的值。当这个内存区进入程序的地址空间后全部清零。

包含data段和bss段的整个区段此时通常称为数据区。

 

 

清除BSS段的一般做法

link脚本一般包含类似语句:

1

2

3

4

5

6

7

8

9

10

11

_bss_start = .;

__bss_start__ = .;

.bss            : 

{

  *(.shbss)

  *(.bss .bss.* .gnu.linkonce.b.*)

  *(COMMON)

}

. = ALIGN (4);

_bss_end = . ;

__bss_end__ = . ;

启动过程的代码一般在汇编做:

1

2

3

4

5

6

7

8

9

    @++++clear the BSS section++++

    ldr     r2,=__bss_start__

    ldr     r3,=__bss_end__

    mov     r12,#0

bss_loop:

    cmp     r2,r3 

    stmltia r2!,{r12}

    blt     bss_loop  

    @----clear the BSS section----

所以不要在C代码中对未初始化的全局变量赋0,因为BSS段会被自动赋0.

单片机运行原理(含bss_data_text段,.ld链接文件,startup.S启动文件介绍) 程序代码(.s 和 .c)源文件会经过预编译、编译、汇编、链接最后生成目标可执行文件,.ld文件是作用在链接过程。链接的作用是:linker_flash.ld:Flash和SRAM内存分配,为Flash构建目标分配代码段和数据段;linker_ram.ld:SRAM内存分配,为RAM构建目标分配代码段和数据段。可以利用.ld文件将函数和变量放置到自定义的地址中。2 常用的关键词介绍ENTRY命令:运行一个程序时第一个被执行到的指令的"入口点"。MEMORY命令:内存块配置命令,一个连接脚本最多一个’MEMO 阅读详情

相关推荐

【C++】static关键字详解

全局静态变量 在全局变量前加上关键字static,全局变量就定义成一个全局静态变量.静态存储区,在整个程序运行期间一直存在。 初始化:未经初始化的全局静态变量会被自动初始化为0(自动对象的值是任意的,除非他被显式初始化); 作用域:全局静态变量在声明他的文件之外是不可见的,准确地说是从定义之处开始,到文件结尾。 局部静态变量 在局部变量之前加上关键字static,局部变量就成为一个局部静态变量。 内存中的位置:静态存储区 初始化:未经初始化的全局静态变量会被自动初始化为0(自动对

Vcrossover的博客 895

.bss段和.data段

BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的或者初始值为0的全局变量的一块内存区域。BSS是英文Block Started by Symbol的简称。BSS段属于静态内存分配。 数据段:数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。 代码段:代码段(code segment/text seg...

qq_34888036的博客 4万+

C#实现跨域访问共享文件夹的账号密码验证方案

本文详细介绍了在C#中实现跨域访问共享文件夹的账号密码验证方案。通过调用Windows API LogonUser函数,结合LOGON32_LOGON_NEW_CREDENTIALS登录类型,可安全模拟指定用户身份,有效解决工作组与域环境间的文件共享访问难题。文章提供了完整的工具类封装、多种实战场景示例及详细的错误排查指南。

pea55的博客 540

BSS段

BSS段的存在是为了节省存储空间,避免将全局变量和静态变量的初始值存储在可执行文件中。BSS段(Block Started by Symbol)是程序在执行之前被初始化为0或空的内存段,它通常存储全局变量和静态变量的未初始化数据。BSS段是可执行程序在内存中的一部分,位于程序的数据段之后。由于BSS段中的数据都是0或空值,因此在可执行文件中只需要记录变量的名称和大小等信息,而不需要存储实际的初始值。总结起来,BSS段是存储全局变量和静态变量未初始化数据的内存段,它在程序加载时自动初始化为0或空值。

qq1816513169的博客 2814

Jetson AGX Orin边缘AI实战:用YOLOv8做目标检测,我的环境配置踩坑与优化记录

本文详细记录了在Jetson AGX Orin上部署YOLOv8目标检测模型的环境配置与优化过程。从JetPack版本确认、PyTorch安装陷阱到Torchvision编译技巧,再到YOLOv8部署和系统级优化,提供了完整的实战指南。特别针对边缘AI设备的特性,分享了CUDA加速、内存管理等性能调优经验,帮助开发者高效完成工业级AI应用部署。

weixin_30839881的博客 376

Starlink vs Kuiper vs OneWeb:三大低轨卫星网络架构对比与实战应用场景解析

本文对比分析了Starlink、Kuiper和OneWeb三大低轨卫星网络架构的技术差异与商业应用场景。从轨道设计、通信性能到商业落地,详细解析了各系统在近地卫星网络领域的独特优势与挑战,为未来全球宽带服务格局提供专业见解。

weixin_29255731的博客 808

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

转自博客园https://www.cnblogs.com/yanghong-hnu/p/4705755.html

weixin_43726152的博客 1165

Amesim与Simulink联合仿真:S-Function接口配置与实战避坑指南

本文详细介绍了Amesim与Simulink联合仿真中S-Function接口的配置方法与实战避坑指南。从环境搭建、编译器配置到S-Function接口实战,逐步解析关键步骤与常见问题解决方案,帮助工程师高效实现多领域系统仿真,特别适合汽车、航空航天等复杂系统建模场景。

weixin_29173777的博客 344

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

bss段:   bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。   bss是英文Block Started by Symbol的简称。   bss段属于静态内存分配。 data段:   数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。   数据段属于静态内存分配。 text段:   代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。 ...

yuhoujiangnan2011的专栏 3045

数字IC后端实战:如何用ICC搞定复杂模块的floorplan与powerplan(附避坑指南)

本文深入解析数字IC后端设计中复杂模块的floorplan与powerplan实战技巧,重点介绍多边形模块边界处理、MTCMOS电源网络优化及存储器摆放陷阱规避。通过Synopsys ICC工具的具体操作示例和项目实战经验,帮助工程师高效解决设计难题,提升芯片性能与可靠性。

weixin_29213525的博客 351

量子密钥分发系统的工程实践(四):FPGA在后处理中的核心实现与优化

本文深入探讨了FPGA在量子密钥分发(QKD)系统后处理中的核心实现与优化策略。文章详细拆解了FPGA如何高效完成原始密钥提取、误码协商和私密放大等关键任务,并分享了流水线设计、资源复用及存储器架构优化等工程实践“心法”,旨在解决高速、实时QKD系统中的性能瓶颈,提升密钥生成率。

t8u9v0的博客 388

C语言的内存分配之Text、Heap、Stack、Data、BSS介绍

C语言占用的内存可以分为5个区: ①代码区(Text Segment):不难理解,就是用于放置编译过后的代码的二进制机器码。 ②堆区(Heap):用于动态内存分配。一般由程序员分配和释放,若程序员不释放,结束程序时有可能由操作系统回收。(其实就是malloc()函数能够掌控的内存区域) ③栈区(Stack):由编译器自动分配和释放,一般用来存放局部变量、函数参数(敲黑板划重点了!)。 ④全局初始化数据区/静态数据区(Data Segment):顾名思义,就是存放全局变量和静态变量的地方。这个

悟已往之不谏 知来者之可追 2829

CANoe信号传输故障排查指南

本文提供了全面的CANoe信号传输故障排查指南,涵盖从硬件连接、通道配置到软件脚本与数据库加载的全链路诊断。针对常见的通道指示灯不亮、信号无法发送及ECU握手失败等问题,给出了基于CANoe工具和CAPL脚本的详细排查步骤与解决方案,帮助工程师系统化定位并解决实车测试中的通信故障。

ice55的博客 258

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

来自:https://www.cnblogs.com/yanghong-hnu/p/4705755.html bss段:   bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。   bss是英文Block Started by Symbol的简称。   bss段属于静态内存分配。     data段:   数据段(data segment)通常...

shareinfo2018 901

CMake教程:C++ CMake自定义find_package并在其它项目使用

find_package 是 CMake 中一个非常重要的命令,用于在系统中找到外部库或包,并将其包含到项目中。: 要查找的包的名称。[version]: 可选的版本号。如果指定了版本号,CMake 会尝试找到该版本或更高版本的包。[REQUIRED]: 如果指定了这个关键字,找不到包时会产生一个错误并终止配置过程。: 指定要查找的包的组件。: 指定可选的组件,即使找不到这些组件,配置过程也会继续。: 指定查找包的模式,CONFIG表示查找配置文件,MODULE表示查找模块文件。

琅嬛福地 1563

OV9734 DATASHEET,完整规格书

OV9734完整规格书,包括电气参数,尺寸规格,寄存器配置表等

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

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

yake827的专栏 806

lwip-2.0.3

lwip是瑞典计算机科学院(SICS)的Adam Dunkels 开发的一个小型开源的TCP/IP协议栈。实现的重点是在保持TCP协议主要功能的基础上减少对RAM 的占用。

(深入理解计算机系统) bss段,data段、text段、堆(heap)和栈(stack)(C/C++存储类型总结)(内存管理)

文章目录bss段data段text段堆(heap)栈(stack)一个程序本质上都是由 bss段、data段、text段三个组成的。 bss段 bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。 bss是英文Block Started by Symbol(由符号启始的区块)的简称。 bss段属于静态内存分配。 data段 数据段(data segment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。 数据段属于静态内存分配。 text段 代码段(code

Dontla的博客 2379

jdk-8u144-linux-x64.tar.gz.

该资源为搭建Linux系统Java环境用,资源的后缀为tar.gz格式的压缩包

SAP B1中文培訓教材_SDK

公司内部培训资料,对开发工具 ,DIAPI, UIAPI,Add-ON有详细解说

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

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

weixin_30371469的博客 154
上一篇: 冒泡两种优化
下一篇: arm工作模式
剑之所向
博客等级 码龄11年 228粉丝 110原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值