代碼段:架構
在採用段式內存管理的架構中,代碼段(code segment / text segment)一般是指用來存放程序執行代碼的一塊內存區域。這部分區域的大小在程序運行前就已經肯定,而且內存區域一般屬於只讀, 某些架構也容許代碼段爲可寫,即容許程序自我修改(self-modifying code)。 在代碼段中,也有可能包含一些只讀的常數變量,例如字符串常量等。ide
操做系統在裝載一個程序時會進行進程地址空間的分段,而代碼段一般處於最底部,即最低地址部分,而堆和棧在高處,因此在容許代碼段可寫的架構上,當堆或棧內存溢出時,代碼段中的數據就會開始被覆蓋。函數
通常來講,能夠簡單地理解爲內存分爲三個部分:靜態區,棧,堆。spa
不少地方沒有把把堆和棧解釋清楚,致使老是分不清楚。其實堆棧就是棧,而不是堆。堆的英文是heap;棧的英文是stack,也翻譯爲堆棧。堆和棧都有本身的特性,這裏先不作討論。操作系統
靜態區:保存自動全局變量和static 變量(包括static 全局和局部變量)。靜態區的內容在總個程序的生命週期內都存在,由編譯器在編譯的時候分配。.net
棧(stack):棧又稱堆棧, 是用戶存放程序臨時建立的局部變量,也就是說咱們函數括弧「{}」中定義的變量(但不包括static聲明的變量,static意味着在數據段中存放變量)。除此之外,在函數被調用時,其參數也會被壓入發起調用的進程棧中,而且待到調用結束後,函數的返回值也會被存放回棧中。因爲棧的先進先出特色,因此棧特別方便用來保存/恢復調用現場。從這個意義上講,咱們能夠把堆棧當作一個寄存、交換臨時數據的內存區。翻譯
棧上的內容只在函數的範圍內存在,當函數運行結束,這些內容也會自動被銷燬。其特色是效率高,但空間大小有限。rest
堆(heap):code
堆是用於存放進程運行中被動態分配的內存段,它的大小並不固定,可動態擴張或縮減。當進程調用malloc系列函數或new 操做符分配內存時,新分配的內存就被動態添加到堆上(堆被擴張);其生命週期由free 或delete 決定。當利用free等函數釋放內存時,被釋放的內存從堆中被剔除(堆被縮減)。在沒有釋放以前一直存在,直到程序結束。其特色是使用靈活,空間比較大,但容易出錯。生命週期
程序:
/* stack07.c */
int foo() {
int a;
int b;
int c;
a = 2;
b = 3;
c = 4;
return 0;
}
int main(int argc, char * argv[]) {
foo();
return 0;
}
彙編:
TITLE stack07.c
.386P
include listing.inc
if @Version gt 510
.model FLAT
else
_TEXT SEGMENT PARA USE32 PUBLIC 'CODE'
_TEXT ENDS
_DATA SEGMENT DWORD USE32 PUBLIC 'DATA'
_DATA ENDS
CONST SEGMENT DWORD USE32 PUBLIC 'CONST'
CONST ENDS
_BSS SEGMENT DWORD USE32 PUBLIC 'BSS'
_BSS ENDS
_TLS SEGMENT DWORD USE32 PUBLIC 'TLS'
_TLS ENDS
FLAT GROUP _DATA, CONST, _BSS
ASSUME CS: FLAT, DS: FLAT, SS: FLAT
endif
PUBLIC _foo
_TEXT SEGMENT
_a$ = -4
_b$ = -8
_c$ = -12
_foo PROC NEAR
; 2 : int foo() {
00000 55 push ebp
00001 8b ec mov ebp, esp
00003 83 ec 0c sub esp, 12 ; 0000000cH
; 3 : int a;
; 4 : int b;
; 5 : int c;
; 6 :
; 7 : a = 2;
00006 c7 45 fc 02 00
00 00 mov DWORD PTR _a$[ebp], 2
; 8 : b = 3;
0000d c7 45 f8 03 00
00 00 mov DWORD PTR _b$[ebp], 3
; 9 : c = 4;
00014 c7 45 f4 04 00
00 00 mov DWORD PTR _c$[ebp], 4
; 10 :
; 11 : return 0;
0001b 33 c0 xor eax, eax
; 12 : }
0001d 8b e5 mov esp, ebp
0001f 5d pop ebp
00020 c3 ret 0
_foo ENDP
_TEXT ENDS
PUBLIC _main
_TEXT SEGMENT
_main PROC NEAR
; 14 : int main(int argc, char * argv[]) {
00021 55 push ebp
00022 8b ec mov ebp, esp
; 15 : foo();
00024 e8 00 00 00 00 call _foo
; 16 : return 0;
00029 33 c0 xor eax, eax
; 17 : }
0002b 5d pop ebp
0002c c3 ret 0
_main ENDP
_TEXT ENDS
END
AT彙編
.file "stack07.c"
.text
.globl _foo
.def _foo; .scl 2; .type 32; .endef
_foo:
LFB0:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
subl $16, %esp
movl $2, -4(%ebp)
movl $3, -8(%ebp)
movl $4, -12(%ebp)
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE0:
.def ___main; .scl 2; .type 32; .endef
.globl _main
.def _main; .scl 2; .type 32; .endef
_main:
LFB1:
.cfi_startproc
pushl %ebp
.cfi_def_cfa_offset 8
.cfi_offset 5, -8
movl %esp, %ebp
.cfi_def_cfa_register 5
andl $-16, %esp
call ___main
call _foo
movl $0, %eax
leave
.cfi_restore 5
.cfi_def_cfa 4, 4
ret
.cfi_endproc
LFE1:
.ident "GCC: (GNU) 5.3.0"
(完)