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应用程序在内存中的布局我们就分析清楚了!

时间: 2024-12-20 05:54:11

linux应用程序地址布局的相关文章

5. Linux应用程序地址布局

程序构成: 在学习Linux应用程序开发时,经常会遇到如下概念:代码段.数据段.BSS段(Block Started by Symbol,又名:未初始化数据段) .堆(heap)和栈(stack).而这些部分也是构成Linux应用程序的重要组成部分. 内存布局: 当Linux应用程序在内存中运行的时候,以上组成部分在内存中布局: 从低地址到高地址分别为:代码段.数据段.BSS段.堆.栈. 堆向高内存地址生长. 栈向低内存地址生长. 下面测试下面的程序: 查看系统的线程: 下面我们看这代码的地址分

第4课-Linux应用程序地址布局

1.应用程序都是由代码段,数据段,BSS段以及堆空间,栈空间组成.2.布局方式:(1)代码段在最低地址处,一般都是从0x8048000开始,这是虚拟地址,每一个应用程序都是这样的(2)数据段紧贴着代码段(3)在往上是BSS段其实也是一种数据段(4)在往上是堆空间,堆空间是往上增长的(5)定不一般是栈空间,栈空间是向下生长2.查看各个段的地址(1)在应用程序里面,末尾处加上while循环,防止程序结束后我们都还来不及查看(2)编译成可执行程序并运行(3)用#ps aux命令查看你的应用程序的PID

Linux C程序存储空间的逻辑布局

原文:http://blog.chinaunix.net/uid-20692625-id-3057053.html --------------------------------------------------------------------- 一.APUE上指出了 Linux C程序存储空间的逻辑布局,对于 X86上的Linux 正文段从 0x08048000单元开始 栈底则在 0xC0000000之下开始 (栈从高地址向低地址生长) 图如下: 二.例程 实现一个函数f(),不用指针

嵌入式linux应用程序调试方法

嵌入式linux应用程序调试方法 四 内存工具 17 4.1 MEMWATCH 17 4.2 YAMD 22 4.3 Electric Fence 24 五 C/C++代码覆盖.性能profiling工具 24 5.1 用gcov来测试代码覆盖率 25 5.2 使用gprof来优化你的C/C++程序 35 四 内存工具 您肯定不想陷入类似在几千次调用之后发生分配溢出这样的情形. 许多小组花了许许多多时间来跟踪稀奇古怪的内存错误问题.应用程序在有的开发工作站上能运行,但在新的产品工作站上,这个应用

Linux C进程内存布局

当程序文件运行为进程时,进程在内存中获得空间.这个空间是进程自己的内存空间.每个进程空间按照如下方式分为不同区域: 进程内存空间布局图 text:代码段.存放的是程序的全部代码(指令),来源于二进制可执行文件中的代码部分 initialized data(简称data段)和uninitialized data(简称bss段)组成了数据段.其中data段存放的是已初始化全局变量和已初始化static局部变量,来源于二进制可执行文件中的数据部分: bss段存放的是未初始化全局变量和未初始化stati

linux系统进程的内存布局

内存管理模块是操作系统的心脏:它对应用程序和系统管理非常重要.今后的几篇文章中,我将着眼于实际的内存问题,但也不避讳其中的技术内幕.由于不少概念是通用的,所以文中大部分例子取自32位x86平台的Linux和Windows系统.本系列第一篇文章讲述应用程序的内存布局. 在多任务操作系统中的每一个进程都运行在一个属于它自己的内存沙盘中.这个沙盘就是虚拟地址空间(virtual address space),在32位模式下它总是一个4GB的内存地址块.这些虚拟地址通过页表(page table)映射到

一起talk C栗子吧(第一百三十一回:C语言实例--C程序内存布局三)

各位看官们,大家好.上一回中咱们说的是C程序内存布局的样例,这一回咱们继续说该样例.闲话休提,言归正转.让我们一起talk C栗子吧. 看官们,关于C程序内存布局的样例,我们在前面的两个章回都介绍过了,这一回我们将对前面章回中的内容进行总结和提示. 内存布局总结 C程序的内存布局主要有四个分区:代码区,数据区(data和bss).堆区和栈区.能够使用readelf -S filename查看各个分区的内存地址.这四个分区在内存中从低地址空间開始依次向高地址延伸.我们再次使用前面章回中的图直观地展

C语言程序内存布局

C语言程序内存布局 如有转载,请注明出处:http://blog.csdn.net/embedded_sky/article/details/44457453 作者:[email protected] 一.几个概念 1.栈(Stack) C语言通过栈来维护函数调用上下文,也就是说C中的函数.函数参数列表.局部变量.函数返回值都保存在栈内存中,在完成函数调用之后栈帧随即销毁,至于具体的压栈顺序和上下文维护工作由谁来完成,则取决于函数的调用方式(cdecl/stdcall/fastcall/pasc

《Linux高性能服务器编程》学习总结(七)——Linux服务器程序规范

第七章      Linux服务器程序规范 服务器程序除了需要网络通信外,还应该考虑很多其他的细节,而这些细节很多很杂,但又基本是模板式的.1)服务器程序基本都是以后台形式运行的,没有控制终端,不能接受用户输入,其父进程通常是init.2)服务器程序有一套日志系统.3)服务器程序以某个专门的非root身份运行.4)服务器通常是可配置的.5)服务器进程启动时通常会生成一个PID文件以记录后台进程的PID.6)服务器程序同城需要考虑系统资源和限制. 服务器一般使用syslog函数与rsyslogd守