再说BSS段的清理

本文探讨了裸机程序中全局变量的存储位置及其影响。通过对比分析,明确了链接脚本对于全局变量地址分配的重要性,并非单纯BSS段清理的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

再说BSS段的清理

        以前遇到一个裸机程序不能改变全局变量值的问题,最后迷迷糊糊解决了:手动添加了一个链接脚本,清理了BSS段。问题得以解决,就认定是BSS段清理的问题,全局变量在BSS段中。

       但是现在看这个结论下的有点不全面。根据名著上说BSS段是放未初始化或者初始化为0的全局变量(经手动证实无误),我不想着有问题了。那么把这个功劳全归于BSS段的清理似乎有点勉强了。

       为了验证一下,重新翻出以前的裸机程序,再来看看,这次只添加一个链接脚本,不清理BSS段,结果发现程序也是正常的,这下就彻底的证实了我的假设。原来功劳是“链接脚本”的。但是这位链接脚本是在u-boot中提取的没有仔细分析。

       现在退回到没有解决这个问题之前,经过《 实例说明C语言中初始化和未初始化的全局变量所在不同的段》这个文章,确定初始化为0的全局变量是存在BSS段的,想到查看一下用objdump生成的dis文件,看到下图所示:
 

      全局变量g_val的链接地址是0x8080(32.125k)超出了CPU内部的内存大小(4k)。再看一下加上链接脚本的g_val的链接地址:


      可以看到链接地址是小于4k的。所以能够改动了。
<think>好的,用户想了解BSS的概念和用途。我需要先回忆一下相关的知识点。BSS是程序内存中的一部分,用于存放未初始化的全局变量和静态变量。根据之前提供的引用内容,BSS是“Block Started by Symbol”的缩写,属于静态内存分配区域。 首先,我应该明确BSS的作用。根据引用1和引用4,BSS存放的是未初始化的全局变量,程序加载时由内核清零。这样可以节省可执行文件的空间,因为不需要在文件中存储零值。例如,定义了一个全局变量int global_array[1000],如果在初始化时没有赋值,它就会被放在BSS,而不是数据。 接下来需要解释BSS的特点。根据引用2和引用3,BSS在可执行文件中只记录大小,不实际占用空间。链接器会分配相应大小的内存,并在程序启动时清零。这样设计的好处是减少磁盘上可执行文件的大小,尤其是对于大型未初始化的数组或结构体。 还要比较BSS与数据的不同。数据(data)存放已初始化的全局和静态变量,而BSS存放未初始化的。例如,int initialized = 10;会放在数据,而int uninitialized;则在BSS。 另外,用户可能想知道BSS在内存中的位置。根据引用2,BSS紧跟在数据后面,两者合称为数据区。程序加载时,BSS会被初始化为零,这是由操作系统或加载器完成的。 还需要注意BSS的静态内存分配特性,如引用4提到的,BSS的大小由链接器根据程序中未初始化变量的大小确定,用户无法在运行时动态调整,但可以使用malloc等函数在堆上分配内存。 最后,应该举例子来帮助理解。比如定义多个未初始化的全局变量,它们在BSS占据空间,但不会增加可执行文件的大小。而初始化过的变量则会增加文件大小。 总结起来,回答需要涵盖BSS的定义、用途、与数据的区别、内存分配方式以及实际例子。同时,要确保引用正确的来源,比如引用1到引用4中的相关内容,以增强回答的可信度。</think>### BSS的概念与用途 **BSS**(Block Started by Symbol)是程序内存布局中用于存储**未初始化的全局变量和静态变量**的静态内存区域[^1][^4]。以下是其核心特点与作用: 1. **存储内容** - 存放程序中**未显式初始化**的全局变量和静态变量。例如: ```c int global_uninit; // 未初始化的全局变量,位于BSS static int static_uninit; // 未初始化的静态变量,也位于BSS ``` - 已初始化的全局变量则存储在**数据(data)**中[^3]。 2. **内存初始化** - 程序加载时,操作系统会将BSS的内存**自动清零**。例如,若定义`int array[1000];`,则系统会在运行时分配内存并将其所有元素初始化为0[^1]。 3. **节省可执行文件空间** - BSS在可执行文件中**仅记录大小**,而不实际存储零值数据。例如,一个未初始化的全局数组`int buffer[1024];`不会增加可执行文件的体积,仅在运行时分配内存[^2]。 4. **与数据的区别** - **数据**存储已初始化的变量(如`int x = 5;`),内容直接写入可执行文件。 - **BSS**存储未初始化的变量,仅记录所需空间大小,运行时动态分配并清零。 5. **内存布局示例** 程序的内存区域通常按以下顺序排列(从低地址到高地址): - **代码(text)**:存放可执行指令。 - **数据(data)**:存放已初始化数据。 - **BSS**:存放未初始化数据。 - **堆(heap)**:动态分配的内存。 - **栈(stack)**:函数调用和局部变量。 --- ### 例子说明 假设定义以下变量: ```c int initialized = 10; // 在data,占4字节(假设int为4字节) char uninitialized[100]; // 在BSS,占100字节 ``` - 可执行文件中仅需存储`initialized`的值(10),而`uninitialized`仅记录需要100字节的BSS空间,不占用文件体积。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

袁保康

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值