1. 程式人生 > 其它 >IMX6ULL裸機學習(8)— 清除BSS段

IMX6ULL裸機學習(8)— 清除BSS段

技術標籤:IMX6ULL裸機

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)— 使用連結指令碼連結程式碼
下一篇:
程式碼存放:https://gitee.com/william_william/imx6ull_noos/tree/master/03_links