一. bss介绍:
bss和data的区别: 全局的未初始化变量存在于.bss段中,具体体现为一个占位符; 全局的已初始化变量存于.data段中; .bss是不占用.exe文件空间的,其内容由操作系统初始化(清零); 而.data却需要占用,其内容由程序初始化。 若这样定义一个全局变量:int g_inBss[9] ; 则它在.bss段,这里占用占位符的空间。 若这样定义一个全局变量:int g_inData[9] ={ 1,2,3,4,5,6,7,8,9}; 则它在.data段,程序占用数组全部大小的空间。bss和data的联系: 都在rw区域; bss段在运行起来成为进程之后,占的空间大小和data就相同了。
二. 分析uboot代码中的clearbss段的代码:
_bss_start 和 __bss_start====================================1. u-boot-1.1.6/board/100ask24x0/u-boot.lds......ENTRY(_start)SECTIONS{ . = 0x00000000; . = ALIGN(4); .text : { cpu/arm920t/start.o (.text) board/100ask24x0/boot_init.o (.text) *(.text) } ...... ...... . = ALIGN(4); __bss_start = .; .bss : { *(.bss) } _end = .;}__bss_start 是bss段的起始地址,_end 是bss段的终止地址.====================================2. u-boot-1.1.6/cpu/arm920t/start.S.globl _bss_start_bss_start: .word __bss_start.globl _bss_end_bss_end: .word _end 分析{ .word .word expr {,expr}… 分配一段字内存单元,幵用expr初始化字内存单元(32bit) 关亍 _bss_start 和 _bss_end 都是两个标号,对应着此处的地址。 而两个地址里面分别存放的值是 __bss_start 和 _end, }====================================3. 汇编的清零bss段:clear_bss: ldr r0, _bss_start /* find start of bss segment */ ldr r1, _bss_end /* stop here */ mov r2, #0x00000000 /* clear */clbss_l: str r2, [r0] /* clear loop... */ add r0, r0, #4 cmp r0, r1 ble clbss_l { ldr r0, _bss_start 表示装载 _bss_start 地址中的值,即装载 __bss_start ldr r0, _bss_end 表示装载 _bss_end 地址中的值,即装载 _end }====================================4. 网上找的c语言中的clear_bss, 觉得有问题:void clean_bss(void){ extern int __bss_start, _end; int *p = &__bss_start; for (; p < &_end; p++) *p = 0;}&__bss_start 就是: _bss_start&_end 就是: _bss_end从c语言语法上看,__bss_start和_end和bss段代表bss段的起始地址和终止地址.但是_bss_start和_bss_end却不能代表bss段的起始地址和终止地址, 因此我得出了这个结论: "clean_bss中那个for循环并不能起到清零bss段的作用."