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应用程序在内存中的布局我们就分析清楚了!
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。