我们都知道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段为什么要初始化,清除的更多相关文章

  1. bss段为什么需要初始化?

    我们都知道bss段需要初始化,但是这是为什么呢? 通过浏览资料,我们都会发现,bss段是不会出现在程序下载文件(*.bin *.hex)中的,因为全都是0.如果把它们出现在程序下载文件中,会增加程序下 ...

  2. Part10-C语言环境初始化-Bss段初始化lesson2

    1.BSS段的作用 初始化的全局变量存放在数据段: 局部变量存放在栈中: malloc的存放在堆: 未初始化的全局变量存放在BSS段: 找到bss段的起始与结束地址,往里面添加0,便初始化好了. 打开 ...

  3. 【转】linux代码段,数据段,BSS段, 堆,栈

    转载自 http://blog.csdn.net/wudebao5220150/article/details/12947445  linux代码段,数据段,BSS段, 堆,栈 网上摘抄了一些,自己组 ...

  4. C语言引用连接脚本lds中的符号——清除bss段,c实现方式

    之前我们的启动文件清除bss和拷贝都是通过汇编的方式的实现,但是,我们能够使用C语言,就不使用汇编: 先看连接脚本: SECTIONS { . = 0x30000000; __code_start = ...

  5. 为什么要清除BSS段

    如题,看到uboot里有清除BSS段的代码,想知道这样做的目的是什么啊,BSS段默认值本来就是0了啊,希望大哥大姐们能详细的解说下,谢谢了 bss 段描述了未初始化的全局变量和静态变量的大小等信息,但 ...

  6. C语言初始化——bss段初始化、跃入C、C与汇编

    1.bss段初始化 变量 存放位置 初始化的全局变量 数据段 局部变量 栈 malloc函数分配的 堆 未初始的全局变量 bss段 说明:全局变量在未赋初值时,会被保留到bss段. 测试: #incl ...

  7. [国嵌攻略][044][初始化Bss段]

    BSS段的作用 1.变量存储的空间 初始化的全局变量:数据段 未初始化的全局变量:BSS段 局部变量:栈 动态分配变量:堆 2.为什么要对BSS段初始化 未初始化的全局变量在使用时才被赋值,未了避免在 ...

  8. Bss段的作用及初始化

    初始化的全局变量:数据段 局部变量:栈 malloc:堆 未初始化的全局变量:Bss段 arm-linux-readelf -a 应用程序    可查看文件运行架构.大小端.共享库等信息 初始化Bss ...

  9. 内存布局:栈,堆,BSS段(静态区),代码段,数据段

    简介 我们程序运行的时候都是放在内存里的.根据静态.成员函数.代码段.对象.等等.放在不同的内存分块里.大概分为5块 1  栈 2  堆 3 BSS段-全局区-(静态区) 4 代码段 5 数据段 栈 ...

随机推荐

  1. ACE_linux:读写锁

    1.涉及类 ACE_RW_Thread_Mutex //ACE读写锁ACE_Read_Guard //ACE加读锁ACE_Write_Guard //ACE加写锁ACE_Thread_Manager ...

  2. dataTable 禁止显示信息

    $("#id").DataTable({ "info": false, // 禁止显示信息 });

  3. Javascript的websocket的使用方法

    javascript websocket接口 web实现客户端和服务端双向发送消息的方法有: 轮询,客户端定期向服务端请求: 长轮询,客户端定期向服务端请求,服务端只有有信息发送的时候才返回respo ...

  4. 【BZOJ】1925: [Sdoi2010]地精部落 DP+滚动数组

    题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=1925 题意:输入一个数N(1 <= N <= 4200),问将这些数排列成折线 ...

  5. ubuntu下安装ssh

    vm安装ubunt后,无法连接ssh,一般情况是防火墙的问题,或者SSH没有安装. 防火墙 1.查看防火墙 sudo ufw status 2,关闭防火墙 sudo ufw disable ssh 1 ...

  6. Wix 安装部署(一)同MSBuild 自动生成打包文件 转

    原文地址:http://www.cnblogs.com/stoneniqiu/p/3355086.html 因为项目需要,最近在研究Wix打包部署,园子里也有一些关于wix的博客,方方面面,讲的点各不 ...

  7. 正确配置jstl的maven依赖,jar包冲突的问题终于解决啦

    困扰了两天的问题,非常头疼,今天终于有了解决思路了,说到底,还是对maven不够了解吧.总是抱怨maven不好用,出现各种无厘头的问题,原来这些都是归于对它不够了解不够熟悉,它提供了很好的解决思路,只 ...

  8. zoj 3757&&3758

    3757一个模拟题,简单,但容易错: 3758 大素数判定就行: #include<cstdio> #include<cstring> #include<algorith ...

  9. Twisted 阐述

    原地址:http://bbs.gameres.com/thread_224020.html Firefly为什么使用Twisted?1.基于PythonTwisted是使用Python编写的,强壮的. ...

  10. 中文输入法在vs2010中失效解决方案

    这样你就可以用切换输入法的方式,输入中文咯.     后来用了2次发现还是有问题,后来我就直接把输入法的切换改成ctrl+1,后来使用就一直没有问题.总之,解决方案视具体情况解决.