程序内存分布区域

一、C语言可执行代码结构

名称 内容

代码段 可执行代码、字符串常量
数据段 已初始化全局变量、已初始化全局静态变量、局部静态变量、常量数据
BSS段 未初始化全局变量,未初始化全局静态变量
栈 局部变量、函数参数
堆 动态内存分配

    一般情况下,一个可执行二进制程序(更确切的说,在Linux操作系统下为一个进程单元,在UC/OSII中被称为任务)在存储(没有调入到内存运行)时拥有3个部分,分别是代码段(text)、数据段(data)和BSS段。这3个部分一起组成了该可执行程序的文件。 
    (1)代码段(text segment):存放CPU执行的机器指令。通常代码段是可共享的,这使得需要频繁被执行的程序只需要在内存中拥有一份拷贝即可。代码段也通常是只读的,这样可以防止其他程序意外地修改其指令。另外,代码段还规划了局部数据所申请的内存空间信息。

    代码段(code segment/text segment)通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等。

    (2)数据段(data segment):或称全局初始化数据段/静态数据段(initialized data segment/data segment)。该段包含了在程序中明确被初始化的全局变量、静态变量(包括全局静态变量和局部静态变量)和常量数据。

    (3)未初始化数据段:亦称BSS(Block Started by Symbol)。该段存入的是全局未初始化变量、静态未初始化变量。

    而当程序被加载到内存单元时,则需要另外两个域:堆域和栈域。图1-1所示为可执行代码存储态和运行态的结构对照图。一个正在运行的C程序占用的内存区域分为代码段、初始化数据段、未初始化数据段(BSS)、堆、栈5个部分。

这里写图片描述

#include <stdio.h>

const int    g_A   = 10;         //代码段  
int              g_B   = 20;         //数据段  
static int    g_C   = 30;         //数据段  
static int    g_D;                    //BSS段  
int              g_E;                    //BSS段  
char          *p1;                     //BSS段  
int main( )  
{  
    int           local_A;            //栈  
    int           local_B;            //栈  
    static int    local_C = 0;        //BSS段    
    static int    local_D;            //BSS段    

    char        *p3 = "123456";     //123456在代码段,p3在栈上  

    p1 = (char *)malloc( 10 );      //堆,分配得来得10字节的区域在堆区  
    strcpy( p1, "123456" );         //123456{post.content}放在常量区,编译器可能会将它与p3所指向 的"123456"优化成一块  

    printf("hight address\n");  
    printf("-------------栈--------------\n");  
    printf( "栈,    局部变量,                           local_A, addr:0x%08x\n", &local_A );  
    printf( "栈,    局部变量,(后进栈地址相对local_A低)  local_B, addr:0x%08x\n", &local_B );  
    printf("-------------堆--------------\n");  
    printf( "堆,    malloc分配内存,             p1,      addr:0x%08x\n", p1 );  
    printf("------------BSS段------------\n");  
    printf( "BSS段, 全局变量,       未初始化    g_E,     addr:0x%08x\n", &g_E, g_E );      
    printf( "BSS段, 静态全局变量,   未初始化,   g_D,     addr:0x%08x\n", &g_D );  
    printf( "BSS段, 静态局部变量,   初始化,     local_C, addr:0x%08x\n", &local_C);  
    printf( "BSS段, 静态局部变量,   未初始化,   local_D, addr:0x%08x\n", &local_D);  
    printf("-----------数据段------------\n");  
    printf( "数据段,全局变量,       初始化      g_B,     addr:0x%08x\n", &g_B);  
    printf( "数据段,静态全局变量,   初始化,     g_C,     addr:0x%08x\n", &g_C);  
    printf("-----------代码段------------\n");  
    printf( "代码段,全局初始化变量, 只读const,  g_A,     addr:0x%08x\n\n", &g_A);  
    printf("low address\n");  
    return 0;  
} 

猜你喜欢

转载自blog.csdn.net/jsh13417/article/details/79735162