linux应用程序地址布局

  Linux应用程序在内存中的布局,由高地址到低地址依次为:栈、堆、BSS段、数据段、代码段。代码段的起始地址固定为0x8048000,无论哪一个应用程序它的代码段起始地址一定是0x8048000,这里的地址虚拟地址,映射到不同的物理地址中去。
    查看程序各段的地址
    ps    aux    
    这个命令用于查看进程的ID,比如我运行一个可执行程序addr

    技术分享

    技术分享

    可以看到addr的进程ID是24048。然后用cat命令查看进程在内部的布局
    cat    /proc/进程ID/maps,这里我们是cat    /proc/24048/maps

    技术分享

    从上到下依次为代码段,数据段,堆,栈。包括了他们起始地址和结束地址等信息。然后执行这个范例程序。

    

 1 #include <stdio.h>
 2 
 3 int global_init_a = 1;                              //全局初始化的变量
 4 int global_uinit_a;                                 //全局未初始化的变量
 5 static int static_global_init_a = 1;                 //全局静态初始化变量
 6 static int static_global_uinit_a;                    //全局静态未初始化变量
 7 const int const_global_a = 1;                      //全局常量
 8 
 9 int global_init_b = 1;                              //全局初始化的变量
10 int global_uinit_b;                                 //全局未初始化的变量
11 static int static_global_init_b = 1;                //全局静态初始化变量
12 static int static_global_uinit_b;                   //全局静态未初始化变量
13 const int const_global_b = 1;                       //全局常量
14 
15 
16 void main()
17 {
18     int local_init_a = 1;                           //局部初始化变量
19     int local_uinit_a;                              //局部未初始化变量
20     static int static_local_init_a = 1;             //局部静态初始化变量
21     static int static_local_uinit_a;                //局部静态未初始化变量
22     const int const_local_a = 1;                    //局部常量
23 
24     int local_init_b = 1;                          //局部初始化变量
25     int local_uinit_b;                              //局部未初始化变量
26     static int static_local_init_b = 1;            //局部静态初始化变量
27     static int static_local_uinit_b;               //局部静态未初始化变量
28     const int const_local_b = 1;                   //局部常量
29     
30     int *malloc_p_a;
31     malloc_p_a = malloc(sizeof(int));              //通过malloc分配得到的局部
32 
33     printf("&global_init_a=%p,global_init_a=%d\n",&global_init_a,global_init_a);
34     printf("&global_uinit_a=%p,global_uinit_a=%d\n",&global_uinit_a,global_uinit_a);
35     printf("&static_global_init_a=%p,static_global_init_a=%d\n",&static_global_init_a,static_global_init_a);
36     printf("&static_global_uinit_a%p,static_global_uinit_a=%d\n",&static_global_uinit_a,static_global_uinit_a);
37     printf("&const_global_a=%p,const_global_a=%d\n",&const_global_a,const_global_a);
38 
39     printf("&global_init_b=%p,global_init_b=%d\n",&global_init_b,global_init_b);
40     printf("&global_uinit_b=%p,global_uinit_b=%d\n",&global_uinit_b,global_uinit_b);
41     printf("&static_global_init_b=%p,static_global_init_b=%d\n",&static_global_init_b,static_global_init_b);
42     printf("&static_global_uinit_b%p,static_global_uinit_b=%d\n",&static_global_uinit_b,static_global_uinit_b);
43     printf("&const_global_b=%p,const_global_b=%d\n",&const_global_b,const_global_b);
44 
45     printf("&local_init_a=%p,local_init_a=%d\n",&local_init_a,local_init_a);
46     printf("&local_uinit_a=%p,local_uinit_a=%d\n",&local_uinit_a,local_uinit_a);
47     printf("&static_local_init_a=%p,static_local_init_a=%d\n",&static_local_init_a,static_local_init_a);
48     printf("&static_local_uinit_a%p,static_local_uinit_a=%d\n",&static_local_uinit_a,static_local_uinit_a);
49     printf("&const_local_a=%p,const_local_a=%d\n",&const_local_a,const_local_a);
50 
51     printf("&local_init_b=%p,local_init_b=%d\n",&local_init_b,local_init_b);
52     printf("&local_uinit_b=%p,local_uinit_b=%d\n",&local_uinit_b,local_uinit_b);
53     printf("&static_local_init_b=%p,static_local_init_b=%d\n",&static_local_init_b,static_local_init_b);
54     printf("&static_local_uinit_b%p,static_local_uinit_b=%d\n",&static_local_uinit_b,static_local_uinit_b);
55     printf("&const_local_b=%p,const_local_b=%d\n",&const_local_b,const_local_b);
56 
57     printf("malloc_p_a=%p,*malloc_p_a=%d\n",malloc_p_a,*malloc_p_a);
58 
59     while(1);
60 }

  运行结果

  技术分享

  结果分析:

    全局初始化变量位于数据段
    全局未初始化变量位于数据段
    全局静态初始化变量位于数据段
    全局静态未初始化变量位于数据段
    全局常量位于代码段

    局部初始化变量位于栈
    局部未初始化变量位于栈
    局部静态初始化变量位于数据段
    局部静态未初始化变量位于数据段
    局部常量位于栈

    通过malloc分配的指针位于堆

    这样就分析清楚了。等等,我们好像遗漏了BSS段。其实,BSS段是数据段的一个子集。
    通过read    -S    程序名来分析BSS段

    技术分享

    通过分析可知,全局未初始化变量和全局静态未初始化变量都属于数据段里的BSS段。这样,linux应用程序在内存中的布局我们就分析清楚了!

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。