IMX6ULL裸机学习(8)— 清除BSS段
一、什么是BSS段
bss段(bss segment)通常是指用来存放程序中未初始化的全局变量的一块内存区域。
bss是英文Block Started by Symbol的简称。
bss段属于静态内存分配。
二、修改mian函数
修改main函数如下所示:
#include "uart.h"
#include "led.h"
int mydata = 12315;
const int myconst = 22315;
int my[1024] = {0};
int myzero1 = 0;
int myzero2 = 0;
int main(void)
{
uart_init();
led_init();
putstring("imx6ull\r\n");
putstring("myzero1:");
puthex((unsigned int)myzero1);
putstring("\r\nmyzero2:");
puthex((unsigned int)myzero2);
putstring("\r\n");
while(1)
{
putstring("led on\r\n");
led_on();
delay(1000000);
putstring("led off\r\n");
led_off();
delay(1000000);
}
}
编译烧录运行,可以看到,两个初始化为零的全局变量的值并不为零,这是因为二进制文件中并不包含BSS段
我们打开.dis文件,可以看到bss段的地址如下所示
使用二进制查看器查看文件.bin文件,可以看到,该程序固件只到地址370为止,并不包含bss段
三、清除BSS段
在start.s
中加入如下代码清除bss段代码,其中bss段的开始和结束地址__bss_start
、__bss_end
则是从链接脚本中获取的。
.text /* .text段保存代码,是只读和可执行的,后面的指令都属于.text段。 */
.global _start /* .global表示_start是一个全局符号,会在链接器链接时用到 */
_start: /* 标签_start,汇编程序的默认入口是_start */
/* 1、设置栈 */
ldr sp, =(0x80000000+0x100000) /* 设置栈顶地址 */
/* 2、清除bss段 */
ldr r1, =__bss_start /* 将bss段开始地址存入r1寄存器 */
ldr r2, =__bss_end /* 将bss段结束地址存入r2寄存器 */
b clean_bss
clean:
mov r3, #0 /* 将0存入r3寄存器 */
str r3, [r1], #4 /* 将r3中的值存到r1中的值所指向的地址中, 同时r1中的值加4 */
clean_bss:
cmp r1, r2 /* 比较r1和r2内的值是否相等 */
bne clean /* 如果不相等则跳转到clean标签处,如果相等则往下执行 */
/* 3、跳转到led函数 */
bl main
/* 4、原地循环 */
b .
然后编译运行烧录,这样我们就可以看到变量的值正常了
四、附录
上一篇:IMX6ULL裸机学习(7)— 使用链接脚本链接代码
下一篇:IMX6ULL裸机学习(9)— IMX6ULL的异常和中断
代码存放:https://gitee.com/william_william/imx6ull_noos/tree/master/03_links