35.BSS段的知识
在C语言中,初始化的全局变量是存在数据段的,初始化的局部变量是存在栈中的,用malloc分配的空间是存在堆里的,未初始化的全局变量是存在bss段。
Hello.c:
#include <stdio.h>
int bssdata;
int main(){
bssdata = 2015;
return bssdata;
}
编译,读出可执行文件的信息:
从下面可以看到,定义的未初始化的全局变量的地址是00010530,而bss段的开始地址_bss_start是0001052c,bss段的结束地址_bss_end是00010534。看到定义的未初始化的全局变量是在bss段的。
之所以要对bss进行初始化,是为了避免错误,初始化bss段里的值都是0.
从上面知道,要初始化bss段,需要知道bss段的起始地址和结束地址,其实这两个地址在链接器脚本里有:
上面的bss_start就是bss段的起始地址,bss_end是bss段的结束地址。
clean_bss:
ldr r0, =bss_start
ldr r1, =bss_end
cmp r0, r1 //如果相等则返回,不相等跳到clean_loop处执行。
moveq pc, lr //返回
clean_loop:
mov r2, #0 //先把寄存器r2赋值为0
str r2, [r0], #4 //再把r2寄存器里的值0传给r0,接着r0寄存器加4往后移动
cmp r0, r1 //继续比较
bne clean_loop //不相等则返回继续清0
mov pc, lr //相等则返回
通过上面的操作,就把bss里的地址所指向的值都赋值为零,bss段的初始化结束。