您的位置:首页 > 运维架构 > Linux

linux应用程序(3)---应用程序地址布局

2017-01-12 22:14 197 查看
在linux的应用程序中有代码段,数据段,BSS段,堆,栈。

以上组成部分在内存中的布局是:

1.从低地址到高地址分别为:代码段,数据段,BSS段,堆,栈。

2..堆是向高内存地址生长

3.栈是向低内存地址生长。

那么怎么查看程序在内存中的位置呢?例如通过以下这个程序来总结不同类型的数据在内存中的位置。

#include<stdio.h>

#include<stdlib.h>

int global_init_a = 1;

int global_uninit_a;

static int static_global_init_a=1;

static int static_global_uninit_a;

const int const_global_a=1;

int main()

{
int local_init_a=1;
int local_uninit_a;
static int static_local_init_a=1;
static int static_local_uninit_a;
const int const_local_a=1;

int * malloc_p_a;
malloc_p_a=malloc(sizeof(int));
printf("&global_init_a=%p,global_init_a=%d\n",&global_init_a,global_init_a);
printf("&global_uninit_a=%p,global_uninit_a=%d\n",&global_uninit_a,global_uninit_a);
printf("&static_global_init_a=%p,static_global_init_a=%d\n",&static_global_init_a,static_global_init_a);
printf("&static_global_uninit_a=%p,static_global_uninit_a=%d\n",&static_global_uninit_a,static_global_uninit_a);
printf("&const_global_a=%p,const_global_a=%d\n",&const_global_a,const_global_a);

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

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

}

首先运行程序,要确保程序此时正在运行(可以在程序的末尾添加while(1)),然后用ps aux 来看这个进程的ID,这里假设为3821.

然后cat /proc/3821/maps ,查看maps这个文件,然后查看段的起始地址。

这些段各自的特点:

  代码段:只读,执行,起始地址0x8048000

  数据段:可读写,不可执行

可以通过这些特点来查看程序各段的起始地址。

通过以上的程序的各个变量在各个段的位置,现总结如下:

1.代码段:代码,全局常量const,字符串常量。

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

3.堆:动态分配的区域

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

那么问题来了,怎么不见BSS段了呢?

  (可以用file 程序名来查看程序的属性查看程序是否是ELF格式 的,如果是的话用以下的方法来查看BSS段的地址)

用readelf -S 程序名,来看BSS段的地址。这样可以看到,BSS段是属于数据段的一个子段。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: