IMX6ULL裸機學習(8)— 清除BSS段
阿新 • • 發佈:2021-01-06
技術標籤: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