沒初始化的全局變量僞指令會按照一定方法順序在一區域劃分好變量對應的RAM位址.
已初始化和未初始化的局部變量和全局變量在記憶體中如何分布?
阿基米東 2020-12-31 01:00:22 415 收藏
分類專欄: 嵌入式面試精選 文章标簽: C語言 面試題 記憶體分布 堆棧
版權
玩轉STM32MP1
從 STM32MP1 開始玩轉 Linux
阿基米東
¥9.90
訂閱專欄
在 C 語言中,通常可以把記憶體了解為四個分區:棧、堆、全局/靜态存儲區和常量存儲區。
棧(stack,也稱“堆棧”)
通常是用于存儲在編譯期間就能确定存儲大小的變量,用于在函數作用域内建立,在離開作用域後自動銷毀的變量的存儲區。通常是局部變量、函數參數等的存儲區。它的存儲空間是連續的,兩個緊密挨着定義的局部變量,它們的存儲空間也是緊挨着的。棧的大小是有限的,在 Linux 中可以通過指令 ulimit -s 檢視預設棧空間大小,預設情況下為 8192 KB(即 8MB)。是以如果在程式内部配置設定超大的資料,有可能會出錯。當然,棧空間大小是可以調整的。
堆(heap)
通常是存儲那些在編譯期間不能确定存儲大小的變量,它的存儲空間是不連續的,一般由 malloc(或 new)函數來配置設定記憶體塊,并且需要用 free(delete)函數釋放記憶體。如果程式員沒有釋放掉,那麼就會出現常說的記憶體洩漏問題。需要注意的是,兩個緊挨着定義的指針變量,所指向的 malloc 出來的兩塊記憶體并不一定的是緊挨着的,是以會産生記憶體碎片。另外需要注意的一點是,堆的大小幾乎不受限制,理論上每個程式最大可達 4GB。
全局/靜态存儲區
和“棧”一樣,通常是用于存儲那些在編譯期間就能确定存儲大小的變量,但它用于的是在整個程式運作期間都可見的全局變量和靜态變量(使用 static 修飾)。
常量存儲區
和“全局/靜态存儲區”一樣,通常是用于存儲那些在編譯期間就能确定存儲大小的常量,并且在程式運作期間,存儲區内的常量是全局可見的。這是一塊比較特殊的存儲去,它們裡面存放的是常量,不允許被修改。

是以,局部變量存放在 棧區(stack),如果使用 static 修飾,則存放在全局/靜态區,跟是否初始化無關。全局變量存放在 全局/靜态區,靜态存儲區又包括 BSS 段和資料段,未初始化的全局變量存放在 BSS 段,已初始化的全局變量則存放在 資料段。
擴充閱讀:
BSS段:BSS段(bss segment)通常是指用來存放程式中未初始化的全局變量的一塊記憶體區域。BSS 是英文 Block Started by Symbol 的簡稱。BSS 段屬于靜态記憶體配置設定,其内容由作業系統初始化(清零,裸機程式需要手動清零),BSS 段不占用可執行檔案的空間。
資料段:資料段(data segment)通常是指用來存放程式中已初始化的全局變量的一塊記憶體區域。資料段屬于靜态記憶體配置設定,其内容由程式初始化,需要占用可執行檔案的空間。
代碼段:代碼段(code segment/text segment)通常是指用來存放程式執行代碼的一塊記憶體區域。這部分區域的大小在程式運作前就已經确定,并且記憶體區域通常屬于隻讀,某些架構也允許代碼段為可寫,即允許修改程式。在代碼段中,也有可能包含一些隻讀的常數變量,例如字元串常量等。
————————————————
版權聲明:本文為CSDN部落客「阿基米東」的原創文章,遵循CC 4.0 BY-SA版權協定,轉載請附上原文出處連結及本聲明。
原文連結:https://blog.csdn.net/lu_embedded/article/details/112001324
C規定,未初始化變量的初值為0,這個清0的操作是由啟動代碼完成的,還有已初始化變量的初值的設定,也是由啟動代碼完成的。
為了啟動代碼的簡單化,編譯連結器會把已初始化的變量放在同一個段:.data,這個段的映像(包含了各個變量的初值)儲存在“隻讀資料段”,這樣啟動代碼就可以簡單地複制這個映像到 .data 段,所有的已初始化變量就都初始化了。
而未初始化變量也放在同一個段:.bss,啟動代碼簡單地調用 memset 就可以把所有未初始化變量都清0。
memset:作用是在一段記憶體塊中填充某個給定的值,它是對較大的結構體或數組進行清零操作的一種最快方法
https://zhidao.baidu.com/question/752408126770120804.html
沒初始化的全局變量僞指令會按照一定方法順序在一區域劃分好變量對應的RAM位址.
僞指令類似ORG指定存儲器位置,段位址,微機原理中僞指令定義變量都不占用ROM空間
指令是在執行階段發揮作用的,由CPU(Intel、AMD等)來執行。
僞指令是在編譯階段發揮作用的,由彙編器(MASM、TASM等)來解釋。不占用ROM空間