bss段为什么要初始化,清除
我们都知道bss段需要初始化,但是这是为什么呢?
通过浏览资料,我们都会发现,bss段是不会出现在程序下载文件(*.bin *.hex)中的,因为全都是0。如果把它们出现在程序下载文件中,会增加程序下载文件的大小。实际应用中,通常只需要把bss段的起始地址和结束地址保存起来,而不需要将程序下载文件中出现bss段(一堆0)将来真正运行程序的时候,再根据这两个数据进行bss段的初始化就行了。
以上这段文字是网上的资料说的。但是,我可不可以让bss段出现在程序下载文件中呢?如果这样可以的话,当程序由存储器(例如nandflash)拷贝到内存中时,捎带着会把bss段像data段那样初始化。
实际上是可以这样做的。请看下边的两个链接脚本。
链接脚本一:
SECTIONS {
. = 0x00000000;
.init : AT(0){ head.o init.o nand.o}
. = 0x30000000;
.text : AT(4096) { *(.text) }
.rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)) {*(.rodata*)}
.data ALIGN(4) : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)) { *(.data) }
__bss_start = .;
.bss ALIGN(4) : { *(.bss) *(COMMON) }
__bss_end = .;
}
链接脚本二:
SECTIONS {
. = 0x00000000;
.init : AT(0){ head.o init.o nand.o}
. = 0x30000000;
.text : AT(4096) { *(.text) }
.rodata ALIGN(4) : AT((LOADADDR(.text)+SIZEOF(.text)+3)&~(0x03)) {*(.rodata*)}
.bss ALIGN(4) : AT((LOADADDR(.rodata)+SIZEOF(.rodata)+3)&~(0x03)){ *(.bss) }
.data ALIGN(4) : AT((LOADADDR(.bss)+SIZEOF(.bss)+3)&~(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段相关的几句话。
(1) __bss_start = .;
(2).bss ALIGN(4) : { *(.bss) *(COMMON) }
(3)__bss_end = .;
这里,实际上句(1)是在bss段的起始地址处定义了一个int类型的全局变量__bss_start。虽然,bss段的起始地址处肯定是一个未初始化的全局变量,但是这里算是编译器又在这个位置上又重新定义了一个全局变量。就是说,一个地址有两个名字,它们都能访问这个地址空间。句(3)的解释同句(1)。
接着我们再看一下用C语言写的初始化bss段的程序。
(1)void clean_bss(void)
(2){
(3) extern int __bss_start, __bss_end;
(4) int *p = &__bss_start;
(5)
(6) for (; p < &__bss_end; p++)
() *p = 0;
(8)}
首先,句(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语言引用连接脚本lds中的符号——清除bss段,c实现方式
之前我们的启动文件清除bss和拷贝都是通过汇编的方式的实现,但是,我们能够使用C语言,就不使用汇编: 先看连接脚本: SECTIONS { . = 0x30000000; __code_start = ...
- 为什么要清除BSS段
如题,看到uboot里有清除BSS段的代码,想知道这样做的目的是什么啊,BSS段默认值本来就是0了啊,希望大哥大姐们能详细的解说下,谢谢了 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段(静态区),代码段,数据段
简介 我们程序运行的时候都是放在内存里的.根据静态.成员函数.代码段.对象.等等.放在不同的内存分块里.大概分为5块 1 栈 2 堆 3 BSS段-全局区-(静态区) 4 代码段 5 数据段 栈 ...
随机推荐
- Leetcode按Tag刷题
按照Leetcode的Tag来刷题,从easy到hard刷题 关于如何让Leetcode按难易程度排序,可按以下步骤: 1. 进入Leetcode后,点击code 2.点击code后,可查看所有题目, ...
- [HTML]img标签属性
<img src="image.png" width="" height="" align="absmiddle" ...
- (转载)使用ADOConnet.BeginTrans后,出现错误提示:无法在此会话中启动更多的事务?
Q: 三层结构,在服务器端使用adoconnection连接到sqlserver2000,然后想在 datasetprovider的beforupdaterecord中使用语句: try adocon ...
- 如何实现一个malloc函数
一.概述 1.malloc简介 函数所在头文件:<stdlib.h> 函数原型是:void *malloc (size_t n) 函数功能:在内存的动态存储区中分配一个长度为size的连续 ...
- 关于tabBar的图片不能正常显示问题
可以先把图片的源文件的名称后面加上@2x 这种图片显示不正常问题原因可能是没有二倍图造成的!!
- 通过I2C总线向EEPROM中写入数据,记录开机次数
没买板子之前,用protues画过电路图,实现了通过i2c总线向EEPROM中写入和读出数据. 今天,在自己买的板子上面写关于i2c总线的程序,有个地方忘了延时,调程序的时候很蛋疼.下面说说我对I2c ...
- CATransition的动画效果类型及实现方法--老代码备用参考
实现iphone漂亮的动画效果主要有两种方法,一种是UIView层面的,一种是使用CATransition进行更低层次的控制, 第一种是UIView,UIView方式可能在低层也是使用CATransi ...
- java单例模式使用及注意事项
1. 说明 1)单例模式:确保一个类只有一个实例,自行实例化并向系统提供这个实例 2)单例模式分类:饿单例模式(类加载时实例化一个对象给自己的引用),懒单例模式(调用取得实例的方法如getInstan ...
- jna 使用实例,
有与项目组需要用到C++的一个模块, 需要将一个2维数组传到dll 里面 ,返回一个字符串, 恶心了1天终于完成了, 记录一下,同时也希望能给你带来帮助. java 代码如下, package tes ...
- zepto源码学习-05 ajax
学习zeptoajax之前需要先脑补下,强烈推荐此文http://www.cnblogs.com/heyuquan/archive/2013/05/13/js-jquery-ajax.html 还有A ...