BSS段清零的原因
BSS段存在的意义
BSS段清零的原因是因为这个段是BSS
要说为什么要有BSS的话,历史就比较久远了。 BSS段我所知道的起源是Unix最初的时候(当然,不排除可能有更早的情况)。变量分两种:局部变量、全局变量。
根据C语法的规定,局部变量不设置初始值的时候,其初始值是不确定的,局部变量(不含静态局部变量)的存储位置位于栈上,具体位置不固定。
全局变量(和静态局部变量)有专门数据段存储,初始值是0,具体位置是固定的。
其实说到底,就两种,一种是位置固定(数据段里),一种是位置不固定的(栈上)。
要知道,早期的计算机存储设备是很贵的,而很多时候,数据段里的全局变量都是0(或者没有初始值),那么存储这么多的0到目标文件里其实是没有必要的。所以为了节约空间,在生成目标文件的时候,就把没有初始值(实际就是0)的数据段里的变量都放到BSS段里,这样目标文件就不需要那么大的体积里(节约磁盘空间)。只有当目标文件被载入的时候,加载器负责把BSS段清零(一个循环就可以搞定)。 之后,这个规则慢慢的成为一个标准配置,大多数编译器也就都支持了BSS段。
然后解释几个问题:
Q:为什么局部变量初始值不是0?
A:局部变量初始值也可以是零(在某些语言中就是),但这实际上需要消耗硬件指令去完成,有些时候这种清零的动作意义不大,对于编译器来说也是一种负担,每次调用函数都要消耗指令去清零,负担太大。要知道全局变量在内存中只有一份,局部变量(非静态)可以是多份的,前者一次清零就可以了,后者多次清零,负担太大。
Q:如果BSS不清零可不可以?
A:可以,如果编译器规定BSS段不清零,也是可以的,但这样的话C语言语法就要改了:未初始化的全局变量和静态局部变量,其值是未知的。甚至其它语言也要跟着改语法。
所以,BSS段清零的原因是因为这个段是BSS 现在存储介质这么便宜了,是不是BSS已经没有必要了?当然不是了,介质便宜仅限于PC和数码产品这一块,嵌入式行业永远都不存在存储介质没有限制的情况。
BSS段在由谁清零和在哪里清零?
在系统启动过程中操作系统会进行BSS段的初始化,如下为arm32 linux通过编写汇编在启动阶段对BSS执行了清零操作。