代码段:架构
在采用段式内存管理的架构中,代码段(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"
(完)