bss段为什么需要初始化?
我们都知道bss段需要初始化,但是这是为什么呢?
通过浏览资料,我们都会发现,bss段是不会出现在程序下载文件(*.bin *.hex)中的,因为全都是0。如果把它们出现在程序下载文件中,会增加程序下载文件的大小。实际应用中,通常只需要把bss段的起始地址和结束地址保存起来,而不需要将程序下载文件中出现bss段(一堆0)将来真正运行程序的时候,再根据这两个数据进行bss段的初始化就行了。
以上这段文字是网上的资料说的。但是,我可不可以让bss段出现在程序下载文件中呢?如果这样可以的话,当程序由存储器(例如nandflash)拷贝到内存中时,捎带着会把bss段像data段那样初始化。
实际上是可以这样做的。请看下边的两个链接脚本。
链接脚本一:
SECTIONS {
. = 0x00000000;
.init : AT(){ head.o init.o nand.o}
. = 0x30000000;
.text : AT() { *(.text) }
.rodata ALIGN() : AT((LOADADDR(.text)+SIZEOF(.text)+)&~(0x03)) {*(.rodata*)}
.data ALIGN() : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+)&~(0x03)) { *(.data) }
__bss_start = .;
.bss ALIGN() : { *(.bss) *(COMMON) }
__bss_end = .;
}
链接脚本二:
SECTIONS {
. = 0x00000000;
.init : AT(){ head.o init.o nand.o}
. = 0x30000000;
.text : AT() { *(.text) }
.rodata ALIGN() : AT((LOADADDR(.text)+SIZEOF(.text)+)&~(0x03)) {*(.rodata*)}
.bss ALIGN() : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+)&~(0x03)){ *(.bss) }
.data ALIGN() : AT((LOADADDR(.bss)+SIZEOF(.bss)+)&~(0x03)) { *(.data) }
}
链接脚本一,把bss段放在最后边,arm-linux-gcc编译器默认的会把bss段给忽略掉,也即不会让bss段出现在程序下载文件中(可以通过Jlink软件查看编译后的bin文件)。这种链接脚本也是我们通常见到的方式。
链接脚本二,把bss段放在了rodata段和data段中间,这个时候,arm-linux-gcc编译器并不会把bss段在程序下载文件中删除,也即会把bss段保留下来,最终出现在程序下载文件中。我考虑原因可能是这样的:编译后的地址rodata段、bss段、data段是连续的,也即程序运行时这几个段是连续的;倘若把bss段在程序下载文件中删除,那么程序下载文件中rodata段后边紧接着的是data段;这就要求程序的这两个段需要分别处理,而不能一次性将它们连续拷贝过去。
链接脚本二的方法可以让bss段出现在程序下载文件中。但是,通常都不会这样做,这里之所以这样深钻,只不过是在探究bss段初始化的必要性。我们通常采用的链接脚本一,由于最终程序下载文件中没有bss段,所以必须在应用程序运行前,根据bss段的起始地址和结束地址将bss段初始化。
下边,着重讲一下链接脚本中与初始化bss段相关的几句话。
() __bss_start = .;
().bss ALIGN() : { *(.bss) *(COMMON) }
()__bss_end = .;
这里,实际上句(1)是在bss段的起始地址处定义了一个int类型的全局变量__bss_start。虽然,bss段的起始地址处肯定是一个未初始化的全局变量,但是这里算是编译器又在这个位置上又重新定义了一个全局变量。就是说,一个地址有两个名字,它们都能访问这个地址空间。句(3)的解释同句(1)。
接着我们再看一下用C语言写的初始化bss段的程序。
()void clean_bss(void)
(){
() extern int __bss_start, __bss_end;
() int *p = &__bss_start;
()
() for (; p < &__bss_end; p++)
() *p = ;
()}
首先,句(3)对编译器产生的两个全局变量进行声明。句(4)通过__bss_start取出bss段的起始地址,句(6)通过__bss_end取出bss段的结束地址。
bss段为什么需要初始化?的更多相关文章
- bss段为什么要初始化,清除
我们都知道bss段需要初始化,但是这是为什么呢? 通过浏览资料,我们都会发现,bss段是不会出现在程序下载文件(*.bin *.hex)中的,因为全都是0.如果把它们出现在程序下载文件中,会增加程序下 ...
- Part10-C语言环境初始化-Bss段初始化lesson2
1.BSS段的作用 初始化的全局变量存放在数据段: 局部变量存放在栈中: malloc的存放在堆: 未初始化的全局变量存放在BSS段: 找到bss段的起始与结束地址,往里面添加0,便初始化好了. 打开 ...
- 【转】linux代码段,数据段,BSS段, 堆,栈
转载自 http://blog.csdn.net/wudebao5220150/article/details/12947445 linux代码段,数据段,BSS段, 堆,栈 网上摘抄了一些,自己组 ...
- C语言初始化——bss段初始化、跃入C、C与汇编
1.bss段初始化 变量 存放位置 初始化的全局变量 数据段 局部变量 栈 malloc函数分配的 堆 未初始的全局变量 bss段 说明:全局变量在未赋初值时,会被保留到bss段. 测试: #incl ...
- [国嵌攻略][044][初始化Bss段]
BSS段的作用 1.变量存储的空间 初始化的全局变量:数据段 未初始化的全局变量:BSS段 局部变量:栈 动态分配变量:堆 2.为什么要对BSS段初始化 未初始化的全局变量在使用时才被赋值,未了避免在 ...
- Bss段的作用及初始化
初始化的全局变量:数据段 局部变量:栈 malloc:堆 未初始化的全局变量:Bss段 arm-linux-readelf -a 应用程序 可查看文件运行架构.大小端.共享库等信息 初始化Bss ...
- BSS段 data段 text段 堆heap 和 栈stack
BSS段:BSS段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域.BSS是英文Block Started by Symbol的简称.BSS段属于静态内存分配. 数 ...
- bss段和data段的区别
一般情况下,一个程序本质上都是由 bss段.data段.text段三个组成的——本概念是当前的计算机程序设计中是很重要的一个基本概念.而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大 ...
- linux代码段,数据段,BSS段, 堆,栈(二)
//main.cpp int a = 0; 全局初始化区 char *p1; 全局未初始化区 main() { int b; 栈 char s[] = "abc"; 栈 char ...
随机推荐
- NotificationListenerService不能监听到通知
作者:Hugo链接:https://www.zhihu.com/question/33540416/answer/113706620来源:知乎著作权归作者所有,转载请联系作者获得授权. 背景知识: 所 ...
- 彻底理解android中的内部存储与外部存储
我们先来考虑这样一个问题: 打开手机设置,选择应用管理,选择任意一个App,然后你会看到两个按钮,一个是清除缓存,另一个是清除数据,那么当我们点击清除缓存的时候清除的是哪里的数据?当我们点击清除数据的 ...
- Java基础知识强化之IO流笔记48:IO流练习之 复制单级文件夹案例
1. 复制单级文件夹 数据源:e:\\demo 目的地:e:\\test 分析: A:封装目录 B:获取该目录下的所有文本的File数组 C:遍历该File数组,得到每一个File对象 ...
- arc项目中使用非arc文件
因为之前没有ARC机制,好多比较好的类库都是使用的非ARC,或是有些大牛还是不喜欢用ARC,封装的类也是非ARC的,想要在自己的ARC项目中使用这些非ARC类库,只需要简单的设置一下就可以了. 1.在 ...
- Android开发--UI之Bundle的使用
Android开发–UI之Bundle的使用 最近,把之前学过的东西大体的整理了以下,并且想把学过的心得分享给大家.我自己做了一个小小的demo,以便说明具体的应用. 这里的两个界面是通过第一个界面输 ...
- vim字符编码设置
vim 编码方式的设置 和所有的流行文本编辑器一样,Vim 可以很好的编辑各种字符编码的文件,这当然包括UCS-2.UTF-8 等流行的 Unicode 编码方式.然而不幸的是,和很多来自 Linux ...
- ERROR 1114 (HY000): The table 'adv_date_tmp' is full(Mysql临时表应用)
场景:需要对现在数据库的数据进行批量的进行is_del=1的操作,但是遇到一个问题,在执行sql的时候发现sql不能在查询特定表的时候再嵌套查询来做update的操作,经过讨论,后续我们想到用临时表的 ...
- modelsim脚本文件的编写
第一章 ModelSim介 绍 本指南是为 ModelSim5.5f版本编写的,该版本运行于UNIX和Microsoft Windows 95/98/Me/NT/2000的操作系统环境中.本指南覆盖了 ...
- HDU-1002(简单大数加法)
A + B Problem II Problem Description I have a very simple problem for you. Given two integers A and ...
- initMethod 和 afterPropertiesSet 以及 AwareMethod方法的执行时机
在spring开发中,我们定义bean 经常会需要用到beanFactory对象,这就需要实现BeanFactoryAware这种类型的接口,它有一个setBeanFactory方法 在xml中配 ...