(二)Linux应用程序地址布局

程序构成

在学习Linux应用程序开发时,经常会遇到 如下概念

代码段、

数据段、

BSS段 (Block Started by Symbol,又名:未初 始化数据段) 、

堆(heap)栈(stack)。

 而这些部分也是构成Linux应用程序的重要组 成部分。

内存布局

无论哪一个应用程序它的代码段起始地址一定是0x8048000,这里的地址虚拟地址,映射到不同的物理地址中去。

各段内容

通过命令ps -aux | grep app 可以查找app的pid 

该进程在系统内存中的布局 (maps文件分析)

最上面 /lib 为库在内存中所在的位置 

代码段: 只读  可执行 (r x) 起始地址:    8048000-8049000

数据段: 可写(w)   紧贴着代码段下面的   8049000-804a0000

堆:     heap    (r w)

栈:     stack

#include <stdio.h>

int global_init_a = 1;                              //全局初始化的变量
int global_uinit_a;                                 //全局未初始化的变量
static int static_global_init_a = 1;                 //全局静态初始化变量
static int static_global_uinit_a;                    //全局静态未初始化变量
const int const_global_a = 1;                      //全局常量

int global_init_b = 1;                              //全局初始化的变量
int global_uinit_b;                                 //全局未初始化的变量
static int static_global_init_b = 1;                //全局静态初始化变量
static int static_global_uinit_b;                   //全局静态未初始化变量
const int const_global_b = 1;                       //全局常量


void main()
{
    int local_init_a = 1;                           //局部初始化变量
    int local_uinit_a;                              //局部未初始化变量
    static int static_local_init_a = 1;             //局部静态初始化变量
    static int static_local_uinit_a;                //局部静态未初始化变量
    const int const_local_a = 1;                    //局部常量

    int local_init_b = 1;                          //局部初始化变量
    int local_uinit_b;                              //局部未初始化变量
    static int static_local_init_b = 1;            //局部静态初始化变量
    static int static_local_uinit_b;               //局部静态未初始化变量
    const int const_local_b = 1;                   //局部常量
    
    int *malloc_p_a;
    malloc_p_a = malloc(sizeof(int));              //通过malloc分配得到的局部

    printf("&global_init_a=%p,global_init_a=%d\n",&global_init_a,global_init_a);
    printf("&global_uinit_a=%p,global_uinit_a=%d\n",&global_uinit_a,global_uinit_a);
    printf("&static_global_init_a=%p,static_global_init_a=%d\n",&static_global_init_a,static_global_init_a);
    printf("&static_global_uinit_a%p,static_global_uinit_a=%d\n",&static_global_uinit_a,static_global_uinit_a);
    printf("&const_global_a=%p,const_global_a=%d\n",&const_global_a,const_global_a);

    printf("&global_init_b=%p,global_init_b=%d\n",&global_init_b,global_init_b);
    printf("&global_uinit_b=%p,global_uinit_b=%d\n",&global_uinit_b,global_uinit_b);
    printf("&static_global_init_b=%p,static_global_init_b=%d\n",&static_global_init_b,static_global_init_b);
    printf("&static_global_uinit_b%p,static_global_uinit_b=%d\n",&static_global_uinit_b,static_global_uinit_b);
    printf("&const_global_b=%p,const_global_b=%d\n",&const_global_b,const_global_b);

    printf("&local_init_a=%p,local_init_a=%d\n",&local_init_a,local_init_a);
    printf("&local_uinit_a=%p,local_uinit_a=%d\n",&local_uinit_a,local_uinit_a);
    printf("&static_local_init_a=%p,static_local_init_a=%d\n",&static_local_init_a,static_local_init_a);
    printf("&static_local_uinit_a%p,static_local_uinit_a=%d\n",&static_local_uinit_a,static_local_uinit_a);
    printf("&const_local_a=%p,const_local_a=%d\n",&const_local_a,const_local_a);

    printf("&local_init_b=%p,local_init_b=%d\n",&local_init_b,local_init_b);
    printf("&local_uinit_b=%p,local_uinit_b=%d\n",&local_uinit_b,local_uinit_b);
    printf("&static_local_init_b=%p,static_local_init_b=%d\n",&static_local_init_b,static_local_init_b);
    printf("&static_local_uinit_b%p,static_local_uinit_b=%d\n",&static_local_uinit_b,static_local_uinit_b);
    printf("&const_local_b=%p,const_local_b=%d\n",&const_local_b,const_local_b);

    printf("malloc_p_a=%p,*malloc_p_a=%d\n",malloc_p_a,*malloc_p_a);

    while(1);
}

结果分析:

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


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


    通过malloc分配的指针位于堆

数据存放

1.代码段: 代码,全局常量(const)、字符串常量

2.数据段: 全局变量(初始化以及未初始化的)、静态变量(全局的和局部的、初始化的以及未初始化的) 

3.堆:        动态分配的区域 

4.栈:        局部变量(初始化以及未初始化的,但不包含静 态变量)、局部只读变量(const)

BSS段

其实,BSS段是数据段的一个子集。 使用readelf工具查看

用file查看可执行程序的属性

linux下用gcc编译出来的程序是ELF格式的32位可执行程序   利用readelf可以提取出可程序程序的信息

通过read    -S    程序名来分析BSS段(readelf -S /home/app)

 全局未初始化的变量属于BSS段 

 全局未初始化的静态变量属于BSS段

通过分析可知,全局未初始化变量和全局静态未初始化变量都属于数据段里的BSS段。

猜你喜欢

转载自blog.csdn.net/qq_34863439/article/details/89023384
今日推荐