35.BSS段的知识

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段的初始化结束。

原文地址:https://www.cnblogs.com/FORFISH/p/5188760.html