記憶體空間分幾部分:程式碼片段、資料區段,棧,堆 (收集整理)

來源:互聯網
上載者:User

1.函數代碼存放在程式碼片段。聲明的類如果從未使用,則在編譯時間,會最佳化掉,其成員函數不佔程式碼片段空間。

全域變數或靜態變數,放在資料區段,
局部變數放在棧中,
用new產生的對象放在堆中,

記憶體分為4段,棧區,堆區,代碼區,全域變數區


BSS段:BSS段(bss segment)通常是指用來存放程式中未初始化的全域變數的一塊記憶體地區。

BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體配置。

2.程式碼片段、資料區段、棧是CPU層級的邏輯概念,堆是語言層級的邏輯概念

3.還有一個常量區,其中的內容不許修改。
常見的 char *p = "hello"; 這裡面的"hello"就儲存在常量區

4.如1樓所說,把程式碼片段、資料區段,棧,堆這些並列在一起不太合適
程式碼片段、資料區段、堆棧段,這是一個概念
堆、棧、全域區、常量區,這是另一個概念

5.STACK(棧)臨時局部
HEAP(堆)動態
RW(讀寫)全域
RO(唯讀)代碼
Char* s=”Hello,World”; S中“H”存放在記憶體RO中且不能修改。

6.CPU寄存器:CPU寄存器,其實就是來控制碼段和資料區段的指令及資料讀取的地方,當然,CPU也有自己存放資料的地方,那就是通用寄存器裡的資料寄存器,通常是EDX寄存器,C語言裡有個register,就是把資料放在這個寄存器裡,這樣讀取資料就相當的快了,因為不用去記憶體找,就省去了定址和傳送資料的時間開銷。他還有一些寄存器是用來指示當前程式碼片段的位置、資料區段的位置、堆棧段的位置等等(注意這裡存放的只是相應的代碼或資料在記憶體中的地址,並不是實際的值,然後根據這個地址,通過地址匯流排和資料匯流排,去記憶體中擷取相應的值),不然在執行代碼的時候,指令和資料從哪取呢?呵呵。。。他裡面還有標誌寄存器,用來標識一些狀態位,比如標識算術溢位呀等等。。。。。

————————————————————————————————————————————————————————————————

記憶體分段(筆記) 



在馮諾依曼的體繫結構中必須有:程式碼片段,堆棧段,資料區段

因為馮氏結構,本質就是取址,執行的過程



編譯器和系統在為變數分配是從高地址開始分配的.

全域變數和函數參數在記憶體中的儲存是由低地值到高地址的.

函數參數為什麼會放到堆區呢?

這是因為我們的函數是在程式運行中進行動態調用的.

在函數的編譯階段根本無法確定他會調用幾次,會需要多少記憶體.

即使可以確定那時候就為變數分配好記憶體著實也是一種浪費。

所以編譯器為函數參數選擇動態分配..即在每次調用函數時才為它動態進行分配空間.



####################################################



記憶體分為4段,棧區,堆區,代碼區,全域變數區


BSS段:BSS段(bss segment)通常是指用來存放程式中未初始化的全域變數的一塊記憶體地區。

BSS是英文Block Started by Symbol的簡稱。BSS段屬於靜態記憶體配置。


資料區段:資料區段(data segment)通常是指用來存放程式中已初始化的全域變數的一塊記憶體地區。資料區段屬於靜態記憶體配置。


程式碼片段:程式碼片段(code segment/text segment)通常是指用來存放程式執行代碼的一塊記憶體地區。

這部分地區的大小在程式運行前就已經確定,並且記憶體地區通常屬於唯讀, 某些架構也允許程式碼片段為可寫,即允許修改程式。

在程式碼片段中,也有可能包含一些唯讀常數變數,例如字串常量等。程式碼片段是存放了程式碼的資料,

假如機器中有數個進程運行相同的一個程式,那麼它們就可以使用同一個程式碼片段。


堆(heap):堆是用於存放進程運行中被動態分配的記憶體段,它的大小並不固定,

可動態擴張或縮減。當進程調用malloc等函數分配記憶體時,新分配的記憶體就被動態添加到堆上(堆被擴張);

當利用free等函數釋放記憶體時,被釋放的記憶體從堆中被剔除(堆被縮減)

棧(stack):棧又稱堆棧, 是使用者存放程式臨時建立的局部變數,

也就是說我們函數括弧“{}”中定義的變數(但不包括static聲明的變數,static意味著在資料區段中存放變數)。

除此以外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,並且待到調用結束後,函數的傳回值也會被存放回棧中。

由於棧的先進先出特點,所以棧特別方便用來儲存/恢複調用現場。從這個意義上講,我們可以把堆棧看成一個寄存、交換臨時資料的記憶體區。



(1)記憶體分段和記憶體分頁一樣都是一種記憶體管理技術,分段:許可權保護,分頁:虛擬記憶體.



(2)分段後,程式員可以定義自己的段,各段有獨立的地址空間,象進程的地址空間互相獨立一樣.



(3)同一個類的執行個體分配在一個段中,只有該類的方法可以訪問,如果其他類的方法去訪問,會因為段保護而出錯.可以從硬體上實作類別的資料保護和隱藏


####################################################################


分段好處:


cpu中的段寄存器-------段址(base)和位移值的上限(limit)。

段址:有效地址 中,如果有效地址大於limit,便會引發異常。這樣就可以限制程式不能範圍當前段外的資料,不能訪問其他程式的資料。

物件導向的好處:對象就是一塊連續的記憶體中的資料





寄存器是特殊形式的記憶體,嵌入到處理器內部。


         每個進程需要訪問記憶體中屬於自身的地區,因此,可將記憶體劃分成小的段,按需分發給進程。

寄存器用來儲存和跟蹤進程當前維護的段。位移寄存器(Offset Registers)用來跟蹤關鍵的資料放在段中的位置。


       在進程被載入記憶體中時,基本上被分裂成許多小的節(section)。我們比較關注的是6個主要的節:


(1) .text 節


    .text 節基本上相當於二進位可執行檔的.text部分,它包含了完成程式任務的機器指令。

該節號為唯讀,如果發生寫操作,會造成segmentation fault。在進程最初被載入到記憶體中開始,該節的大小就被固定。


(2).data 節


.data節用來儲存初始化過的變數,如:int a =0 ; 該節的大小在運行時固定的。


(3).bss 節


棧下節(below stack section ,即.bss)用來儲存為初始化的變數,如:int a; 該節的大小在運行時固定的。


(4) 堆節


堆節(heap section)用來儲存動態分配的變數,位置從記憶體的低地址向高地址增長。記憶體的分配和釋放通過malloc() 和 free() 函數控制。


(5) 棧節


棧節(stack section)用來跟蹤函數調用(可能是遞迴的),在大多數系統上從記憶體的高地址向低地址增長。

同時,棧這種增長方式,導致了緩衝區溢位的可能性。


(6)環境/參數節


     環境/參數節(environment/arguments section)用來儲存系統內容變數的一份複製檔案,

進程在運行時可能需要。例如,運行中的進程,可以通過環境變數來訪問路徑、shell 名稱、主機名稱等資訊。

該節是可寫的,因此在格式串(format string)和緩衝區溢位(buffer overflow)攻擊中都可以使用該節。

另外,命令列參數也保持在該地區中。



################################################################################


以win32程式為例。

程式執行時,作業系統將exe檔案對應入記憶體。exe檔案格式為頭資料和各段資料群組成。


頭資料說明了exe檔案的屬性和執行環境,段資料又分為資料區段,程式碼片段,資源段等,段的多少和位置由頭資料說明。

也就是說,不僅僅只是程式碼片段和資料區段。這些段由不同的編譯環境和編譯參數控制,由編譯器自動產生exe的段和檔案格式。

當作業系統執行exe時,會動態建立堆棧段,它是動態,並且屬於作業系統執行環境。


也就是說,程式在記憶體的映射一個為exe檔案對應,包括資料區段、程式碼片段等它是不變的。

另一個為堆棧段,它是隨程式運行動態改變的。


1、編譯器把原始碼轉化成分立的目標代碼(.o或者.obj)檔案,這些檔案中的代碼已經是可執行檔機器碼或者是中間代碼。

但是其中變數等事物的地址只是一些符號。   

2、接下來是通過連結器處理這些目標代碼,主要目的就是把分立的目標代碼串連成一份完整的可執行代碼,

並將其中的地址符號換成相對位址。如果這時候產生錯誤,我們就可以得到一份地址符號列表,而不是變數列表。   

3、執行程式的時候作業系統分配足夠的記憶體空間,建立好系統支撐結構後把二進位可執行代碼讀入記憶體中。

在讀入過程中記憶體首址就成了程式的“絕對位址”(實際上還是相對位址,不過是作業系統裡的相對位址了)。

於是絕對位址+相對位址(就是位移量)就得到了變數的地址。   

因此,CS的值是由系統填入的,而其它S寄存器的值則是根據程式碼中附加的資訊計算後得到的。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.