SECTIONS 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++)
(7) *p = 0;
(8)}
首先,句(3)对编译器产生的两个全局变量进行声明。句(4)通过__bss_start取出bss段的起始地址,句(6)通过__bss_end取出bss段的结束地址。

参考链接:
https://www.cnblogs.com/amanlikethis/p/3384743.html

SECTIONS bss段初始化分析相关推荐

  1. 链接全局变量再说BSS段的清理

    废话就不多说了,开始... 再说BSS段的清算 以前遇到一个裸机程序不能改变全局变量值的问题,最后模模糊糊处理了:手动添加了一个链接脚本,清算了BSS段.问题得以处理,就认定是BSS段清算的问题,全局 ...

  2. text段,data段,bss段,堆和栈

    红色部分为问题部分 堆和栈的区别 一.预备知识-程序的内存分配 一个由c/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)- 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等 ...

  3. 实例说明代码段(.text)、数据段(.data)、bss段、只读数据段(.rodata)、堆栈的划分依据

    目录 程序实例介绍各个段内容.分析段(segment)分布 分析代码段(.text).数据段(.data).bss段.只读数据段(.rodata)划分依据 程序实例介绍各个段内容.分析段(segmen ...

  4. 数据段、代码段、堆栈段、BSS段

    在linux中,进程在内存中一般会分为5个段,用来存放从磁盘载入的程序代码,等. 这五个段分别是: BSS段: 通常用来存放程序中未初始化的全局变量的一块内存区域.属于静态内存分配. 问题:全局变量不 ...

  5. text段、data段和bss段知识介绍

    一.总体概述 1.bss(可读可写)      bss是英文Block Started by Symbol的简称,通常是指用来存放程序中未初始化的全局变量的一块内存区域,在程序载入时由内核清0.BSS ...

  6. 关于text段、data段和bss段

    根据APUE,程序分为下面的段:.text, data (initialized), bss, stack, heap. data/bss/text: text段在内存中被映射为只读,但.data和. ...

  7. 代码段、数据段、bss段

    编译器在编译程序的时候,将程序中的所有的元素分成了一些组成部分,各部分构成一个段,所以说段是可执行程序的组成部分. 代码段:代码段就是程序中的可执行部分,直观理解代码段就是函数堆积组成的. 数据段(也 ...

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

    文章目录 bss段 data段 text段 堆(heap) 栈(stack) 一个程序本质上都是由 bss段.data段.text段三个组成的. 存储类型总结 bss段 bss段(bss segmen ...

  9. 清除BSS段的一般做法

    link脚本一般包含类似语句: 1 2 3 4 5 6 7 8 9 10 11 _bss_start = .; __bss_start__ = .; .bss            :  {   *( ...

最新文章

  1. 2022-2028年中国民用航空装备行业市场需求与投资规划分析报告
  2. ASP.NET 3.5 的 ListView 控件与 CSS Friendly
  3. JVM调优常用参数配置
  4. SAP Cloud Platform上Destination属性为odata_gen的具体用途
  5. 国内初创企业选择云计算服务器价格对比
  6. 2019阿里云618大促主会场全攻略
  7. 电脑中计算机右键管理无法打开,win8系统计算机右键菜单中的管理打不开怎么办...
  8. easyui tab 引用html,jQuery插件EasyUI获取当前Tab中iframe窗体对象的方法
  9. 素数判断的java方法_java判断数字是否是素数的方法
  10. 晨哥真有料丨你太容易被得到了!
  11. 在SQL Server中导入数据库(.mdf格式)
  12. 2019Thinking(上) -- 一个前端开发者的个人思考
  13. eclipse 图形界面设计技巧——JLabel
  14. 433m的模块含义及该如何适当的选择对应的无线模块
  15. animate.css 梦幻西游动画
  16. win10内存占用率过高怎么办?Win10电脑内存占用率很高的原因和解决方法
  17. 计算机毕业设计 SpringBoot+Vue作业帮课程管理系统 作业帮信息管理系统 作业帮试题管理系统
  18. PC微信hook学习笔记(一)—— 获取个人信息
  19. 前端:3分钟实现一个共享桌面,还能听见麦克风声音哦
  20. 云原生会统领SaaS服务的原因

热门文章

  1. 一文吃透JAVA定时器格式
  2. 基于Golang的CLI 命令行程序开发
  3. Docker入门六部曲——服务
  4. php错误提示如何查询,php-如何显示我的MySQLi查询错误?
  5. 2022-2028年中国钛合金行业深度调研及投资前景预测报告
  6. Docker入门之 - 如何安装Docker CE
  7. 聊一聊Spring中的线程安全性
  8. LeetCode简单题之1比特与2比特字符
  9. LLVM基础技术图例
  10. AI推理与Compiler