IMX6ULL裸机学习(8)— 清除BSS段

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

猜你喜欢

转载自blog.csdn.net/qq_38113006/article/details/112253716