esp32 c6開發板樂鑫科技的代理商C語言程序堆和棧,程序運行時,C語言程序中的變量和數據可以存儲在內存的靜態存儲區、?;蚨阎?。在程序編譯階段分配靜態存儲空間,靜態存儲空間的變量和數據在整個程序運行期間內有效。靜態存儲區中包含程序代碼段和數據段。編譯后生成的所有程序指令存儲在代碼段。
數據段包括只讀數據段、已初始化的讀/寫數據段和未初始化段(BSS)三部分只讀數據段是程序中使用的一些不會被更改的數據,放置在系統的 ROM 空間經const 修飾的變量,以及程序中使用的常數等常量通常存放在該段中。
已初始化數據段是在程序中聲明,并且具有初值的變量。esp32 c6開發板樂鑫科技的代理商這些變量占用存儲器有空間,位于可讀/寫的內存區域內,并且有初始值,以供程序運行時讀/寫。已經初始化的全局變量和靜態(static)局部變量存放在該段中。
未初始化段(BSS)通常存放程序中未初始化的全局變量和靜態變量,是可讀/寫內存區域。在系統啟動的初始化階段創建棧和堆的空間,棧保存程序中的局部和臨時變量,堆為程序中動態申請的內存提供存儲空間。因此,棧和堆常稱為動態存儲區。esp32 c6開發板樂鑫科技的代理商BSS 段、棧和堆空間的大小不會影響可執行程序文件的長度。執行函數時,函數內的局部戀量都可以在??臻g上分配存儲單元。退出函數時這些存儲單元將被自動釋放。
運行時,程序中用 malloc 或 new 在堆中申請內存資源,用free 或 delete 釋放動態申請的內存資源。動態內存的生存周期從用程序申請成功開始到在程序中釋放結束。動態申請的內存必須在程序中釋放,否則會出現內存泄漏。
在 C語言中,變量的作用域不僅影響變量的時效性,還影響變量在內存中的區域。在函數內部定義的變量稱為局部變量(Local Variable),它的作用域也僅限于麗數內部,存儲在??臻g中。在所有函數外部定義的變量稱為全局變量(Global Varia-ble),它的默認作用域是整個程序,也就是所有的代碼文件,包括源文件(.c 文件)和頭文件(.h 文件)。如果給全局變量加上 static 關鍵字,則它的作用域就變成了當前文件。esp32 c6開發板樂鑫科技的代理商鏈接時在靜態區中為全局變量分配內存空間。在示例 8.3 中,鏈接時將全局變量 status 和 value分配到靜態存儲區,其中 static 關鍵字限定變量能否被其他文件中的代碼訪問,而代碼塊域中的變量 t、ptr 和 local_st 則要根據不同的定義方法,分配到不同的區域,其中t和 ptr 是局部變量,存儲在棧中;local_st 是靜態變量,存儲在靜態存儲區中。ptr 指向由 malloc 分配的空間。
示例 8.3:變量類型。
/ *main.c*/
# include <stdio.h>
# include <stdlib.h>
static int status; //靜態全局變量,靜態存儲區
int value; //全局變量,靜態存儲區
int main(void)
{
intt = 0; //局部變量,棧上申請
int *ptr = NULL; //指針變量
static int local st = 0; //靜態變量
local st ++;
t= local_st;
ptr = (int *)malloc(sizeof(int)); //從堆上申請空間
if(ptr != NULL)
{
free(ptr);
ptr = NULL; //free 后需要將 ptr 置空。
}
}
在運行 C語言用戶程序前系統必須創建和分配棧和堆空間,確定內存中棧和堆的位置和太小。棧和堆的空間過小,可能導致程序運行錯誤。esp32 c6開發板樂鑫科技的代理商如果擴大棧和堆的空間,將增加對系統內存資源的要求。因此需要根據系統中程序的實際情況,設置棧和堆的大小。
通常,在編寫系統啟動程序時用宏定義,或者用序工程屬性的“code”選項設置城和的大小。例如,在 ARM 處理器 s3c2410A 的啟動程序 s3c2410A.s 中,用宏定以棧和堆的大小。
/*s3c2410A.s*/
UND Stack_Size EOU 0x00000000 //未定義異常模式
svc_Stack_Size EQU 0x00000008 /監督模式棧
ABT Stack_Size EQU 0x00000000 /讀/寫異常模式
FIQ_Stack_Size EQU 0x00000000 /快速中斷模式
IRO Stack_Size EQU 0x00000080 /中斷模式
USR Stack_Size EQU 0x00000400 /用戶模式
Stack_Size EQU (UND_Stack_Size + SVC_Stack Size + ABT_Stack_Size +
\FIQ_Stack_Size + IRQ_Stack_Size + USR Stack_size) //總空間
Heap_Size EQU 0x00000000 //堆空間大小
Heap_Size EQU 0x00000000Heap_Size EQU 0x00000000
如圖 8.4 所示為 SEGGER Embedded Studio for RISC-V 中,使用程序工程選項設置棧和堆大小的窗口。相應的鏈接腳本文件中的內容如下:
/*hello.ld*/
__HEAPSIZE__= 1024;
__STACKSIZE__=1024;
引導程序在進入C語言用戶主程序 main()前設置棧和堆空間。
引導程序可以直接跳到用戶 (main)函數,也可以先調用庫函數“__main”,然后從函數“ __main”中跳到用戶函數 main()。
Runtime Memory Area
.Heap Size 1024 bytes
.Stack Size 1024 bytes
圖8.4堆棧大小設置選項
在riscv-crto.s 中,引導程序利用下列兩行聲明棧和堆段,鏈接器根據設置的棧和堆的大小創建棧和堆。esp32 c6開發板樂鑫科技的代理商引導程序將棧頂指針寫入 sp 寄存器。堆的起始地址為“__stack_end__-__STACK_SIZE__-__HEAP_SIZE__”。
/*riscv-crt0.s*/
.section .stack, "wa",% nobits
.section .heap, "wa",% nobits
_start:
La sp,__stack_end__ //設置棧
......