bss,data,text,rodata,堆,栈,常量段

来源:互联网 发布:如何写专利 知乎 编辑:程序博客网 时间:2024/05/19 14:01
//红色部分为问题部分

section 结构
SECTIONS {
...
secname start BLOCK(align) (NOLOAD) : AT ( ldadr )
  { contents } >region :phdr =fill
...
}
secname:段名
contents:决定哪些内容存放在此段
start:本段的连接地址(实际运行地址)
AT(ldadr):存储地址(加载的地址)

//例子U-Boot.lds代码(根据上面的section的介绍,虽能大体看懂,但是还是有些许疑惑)
SECTIONS
{
    . = 0x00000000;      // ?????此处对应section结构中哪个标识,我觉得应该是存储地址吧?? 但却没有 AT 标识    
    . = ALIGN(4);        //此处应该是4字节对齐的意思,???? 但对应section结构中的哪个标志不是很明白

    .text      :            //此处应该是secname 段名
   {
         cpu/arm920t/start.o
        (.text)          //大括号,应该为contents段,指示该段存放的内容
        *(.text)
   }
   . = ALIGN(4);                    //以下类似
   .rodata : { *(.rodata) }
   . = ALIGN(4);
   .data : { *(.data) }
   . = ALIGN(4);
   .got : { *(.got) }
   . = .;

   __u_boot_cmd_start = .;
   .u_boot_cmd : { *(.u_boot_cmd) }
   __u_boot_cmd_end = .;

   . = ALIGN(4);
   __bss_start = .;
   .bss : { *(.bss) }
   _end = .;
}

 

问题1,二进制文件不包含BSS段,那把BSS段放在哪
答:修改有1000个全局变量,难道要BIN里要存1000个0吗?在链接脚本里把BSS段组织在一起,记下它的起始地址、结束地址,重定位后把这块内存清0即可

问题2:全局变量不初始化的话默认初始化为零,干嘛还要手动清零
答:因为它是在BSS段的

bss段:

BSS段(bsssegment)通常是指用来存放程序中未初始化的全局变量的一块内存区域BSS是英文BlockStarted by Symbol的简称。BSS段属于静态内存分配。

data段:

数据段(datasegment)通常是指用来存放程序中已初始化的全局变量的一块内存区域。数据段属于静态内存分配。

text段:

代码段(codesegment/textsegment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读,某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

rodata

存放C中的字符串和#define定义的常量

heap堆:

堆是用于存放进程运行中被动态分配的内存段,它的大小并不固定,可动态扩张或缩减。当进程调用malloc等函数分配内存时,新分配的内存就被动态添加到堆上(堆被扩张);当利用free等函数释放内存时,被释放的内存从堆中被剔除(堆被缩减)

stack栈:

是用户存放程序临时创建的局部变量,也就是说我们函数括弧“{}”中定义的变量(但不包括static声明的变量,static意味着在数据段中存放变量)。除此以外,在函数被调用时,其参数也会被压入发起调用的进程栈中,并且待到调用结束后,函数的返回值也会被存放回栈中。由于栈的先进先出特点,所以栈特别方便用来保存/恢复调用现场。从这个意义上讲,我们可以把堆栈看成一个寄存、交换临时数据的内存区。

 

常量段:

常量段一般包含编译器产生的数据(与只读段包含用户定义的只读数据不同)。比如说由一个语句a=2+3编译器把2+3编译期就算出5,存成常量5在常量段中

 

一般情况下,一个程序本质上都是由 bss段、data段、text段三个组成的——本概念是当前的计算机程序设计中是很重要的一个基本概念。而且在嵌入式系统的设计中也非常重要,牵涉到嵌入式系统运行时的内存大小分配,存储单元占用空间大小的问题。

在采用段式内存管理的架构中(比如intel的80x86系统),bss段(Block Started by Symbol segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域,一般在初始化时bss 段部分将会清零(bss段属于静态内存分配,即程序一开始就将其清零了)。

比如,在C语言程序编译完成之后,已初始化的全局变量保存在.data 段中,未初始化的全局变量保存在.bss 段中。   

l          text和data段都在可执行文件中(在嵌入式系统里一般是固化在镜像文件中),由系统从可执行文件中加载;

l          而bss段不在可执行文件中,由系统初始化

 

编译两个小程序如下:

程序1:

int ar[30000];
void main()
{

    ......

}

 

程序2:

int ar[300000] =  {1, 2, 3, 4, 5, 6 };
void main()
{

    ......

}

    发现程序2编译之后所得的.exe文件比程序1的要大得多。 为什么?

区别很明显,一个位于.bss段,而另一个位于.data段,两者的区别在于

l          全局的未初始化变量存在于.bss段中,具体体现为一个占位符;全局的已初始化变量存于.data段中;

l          而函数内的自动变量都在栈上分配空间。

l          .bss是不占用.exe文件空间的,其内容由操作系统初始化(清零);

l          而.data却需要占用,其内容由程序初始化,因此造成了上述情况。

 

注意:

l          bss段(未手动初始化的数据)并不给该段的数据分配空间,只是记录数据所需空间的大小。

l          data(已手动初始化的数据)段则为数据分配空间,数据保存在目标文件中。

l          DATA段包含经过初始化的全局变量以及它们的值。

l          BSS段的大小从可执行文件中得到,然后链接器得到这个大小的内存块,紧跟在数据段后面。当这个内存区进入程序的地址空间后全部清零。包含DATA和BSS段的整个区段此时通常称为数据区。

原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 小米手机sd卡写入失败怎么办 没有检测到sd卡怎么办 e站图片配额用尽怎么办 内存卡密码忘了怎么办 电脑上酷狗音乐播放失败怎么办 播放失败不支持该文件怎么办 手机山寨云资源失效怎么办 支付密码输错了怎么办 微信密码锁定了怎么办 电脑网易云音乐闪退怎么办 逆战耳机电流声怎么办 肠道感染一直吃药治不好怎么办 如果24小时以后还没到账该怎么办 在游戏平台充值没到账该怎么办 充值豪华黄钻没到账该怎么办 起点签到签满了怎么办 ipad锁屏声音小怎么办 扣扣邮箱文件超大了怎么办 网易邮箱图片已过期怎么办 邮箱里面的文件过期了怎么办 邮箱发的文件过期了怎么办 邮箱发送的文件过期怎么办 小米4s开不开机怎么办 小米平板关机后开不开机怎么办 公司老板跑路了社保怎么办 公司老板跑路社保怎么办 公司被公安局查封社保怎么办 小米四开不了机怎么办 小米的手机后壳裂了怎么办 公司没钱拖欠员工社保怎么办 小米note充不进去电怎么办 公司欠社保没交怎么办 公司不给转社保怎么办 小米note充电特别慢怎么办 小米小米note2充电慢怎么办 小米note充电红灯不闪烁怎么办 小米note充电红灯闪烁怎么办 小米note2突然充电慢怎么办 充电小米note2手机闪烁怎么办 小米6x上网慢怎么办 小米5数据上网慢怎么办