Linux应用程序在内存中的布局,由高地址到低地址依次为:栈、堆、BSS段、数据段、代码段。代码段的起始地址固定为0x8048000,无论哪一个应用程序它的代码段起始地址一定是0x8048000,这里的地址虚拟地址,映射到不同的物理地址中去。
查看程序各段的地址
ps aux
这个命令用于查看进程的ID,比如我运行一个可执行程序addr
可以看到addr的进程ID是24048。然后用cat命令查看进程在内部的布局
cat /proc/进程ID/maps,这里我们是cat /proc/24048/maps
从上到下依次为代码段,数据段,堆,栈。包括了他们起始地址和结束地址等信息。然后执行这个范例程序。
#include <stdio.h> int global_init_a = ; //全局初始化的变量
int global_uinit_a; //全局未初始化的变量
static int static_global_init_a = ; //全局静态初始化变量
static int static_global_uinit_a; //全局静态未初始化变量
const int const_global_a = ; //全局常量 int global_init_b = ; //全局初始化的变量
int global_uinit_b; //全局未初始化的变量
static int static_global_init_b = ; //全局静态初始化变量
static int static_global_uinit_b; //全局静态未初始化变量
const int const_global_b = ; //全局常量 void main()
{
int local_init_a = ; //局部初始化变量
int local_uinit_a; //局部未初始化变量
static int static_local_init_a = ; //局部静态初始化变量
static int static_local_uinit_a; //局部静态未初始化变量
const int const_local_a = ; //局部常量 int local_init_b = ; //局部初始化变量
int local_uinit_b; //局部未初始化变量
static int static_local_init_b = ; //局部静态初始化变量
static int static_local_uinit_b; //局部静态未初始化变量
const int const_local_b = ; //局部常量 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();
}
运行结果
结果分析:
全局初始化变量位于数据段
全局未初始化变量位于数据段
全局静态初始化变量位于数据段
全局静态未初始化变量位于数据段
全局常量位于代码段
局部初始化变量位于栈
局部未初始化变量位于栈
局部静态初始化变量位于数据段
局部静态未初始化变量位于数据段
局部常量位于栈
通过malloc分配的指针位于堆
这样就分析清楚了。等等,我们好像遗漏了BSS段。其实,BSS段是数据段的一个子集。
通过read -S 程序名来分析BSS段
通过分析可知,全局未初始化变量和全局静态未初始化变量都属于数据段里的BSS段。这样,linux应用程序在内存中的布局我们就分析清楚了!
linux应用程序地址布局的更多相关文章
-
linux应用程序地址布局,王明学learn
linux应用程序地址布局 在学习Linux应用程序开发时,经常会遇到如下概念:代码段.数据段.BSS段(Block Started by Symbol,又名:未初始化数据段).堆(heap)和栈(s ...
-
[国嵌攻略][072][Linux应用程序地址布局]
程序构成 代码段.数据段.BSS段(Block Started by Symbol,又叫:未初始化数据段).堆(heap)和栈(stack).这些部分构成了Linux应用程序的重要组成部分. 内存布局 ...
-
7、Linux应用程序地址布局
程序构成 在学习Linux应用程序开发时,经常会遇到如下概念: 代码段.数据段.BSS段(Block Started by Symbol,又名:未始化数据段) .堆(heap)和栈(stack).始化 ...
-
linux C 程序内存布局
参考: 1. http://www.cnblogs.com/clover-toeic/p/3754433.html 2. http://www.cnblogs.com/jacksu-tencent/p ...
-
Linux应用程序的地址布局
转载自:http://blog.csdn.net/embedded_hunter http://www.360doc.com/content/12/0405/00/1671317_200882538. ...
-
01-Coredump核心转存&;&;Linux程序地址分析【转】
转自:http://www.itwendao.com/article/detail/404132.html 目录(?)[-] 一Core Dump核心转存 二Linux程序地址分析 一Core Dum ...
-
Linux C程序存储空间的逻辑布局
原文:http://blog.chinaunix.net/uid-20692625-id-3057053.html ------------------------------------------ ...
-
Linux C 程序 进程控制(17)
进程控制 1.进程概述现代操作系统的特点在于程序的并行执行.Linux是一个多用户多任务的操作系统.ps .pstree 查看进程进程除了进程id外还有一些其他标识信息,可以通过相应的函数获得.// ...
-
linux系统进程的内存布局
内存管理模块是操作系统的心脏:它对应用程序和系统管理非常重要.今后的几篇文章中,我将着眼于实际的内存问题,但也不避讳其中的技术内幕.由于不少概念是通用的,所以文中大部分例子取自32位x86平台的Lin ...
随机推荐
-
快速入门系列--WebAPI--04在老版本MVC4下的调整
WebAPI是建立在MVC和WCF的基础上的,原来微软老是喜欢封装的很多,这次终于愿意将http编程模型的相关细节暴露给我们了.在之前的介绍中,基本上都基于.NET 4.5之后版本,其System.N ...
-
Android实例-解决虚拟键盘遮挡问题(XE8+小米2)
结果: 1.可以自动向上移动,来防遮挡,但同时发现个问题,如果是按硬件返回没有问题,要是点输入法(QQ.百度输入法)上的隐藏就不行了. 2.点击Edit2后出现输入法,点输入法上的隐藏后, 再点Edi ...
-
HDU 4749 Parade Show 2013 ACM/ICPC Asia Regional Nanjing Online
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4749 题目大意:给一个原序列N,再给出一个序列M,问从N中一共可以找出多少个长度为m的序列,序列中的数 ...
-
What does the number on the visual studio solution icon represent?
The numbers correspond to the internal version numbers of various editions of Visual Studio http://e ...
-
android6.0源码分析之Camera API2.0下的Capture流程分析
前面对Camera2的初始化以及预览的相关流程进行了详细分析,本文将会对Camera2的capture(拍照)流程进行分析. 前面分析preview的时候,当预览成功后,会使能ShutterButto ...
-
select的onchange事件获取不了option的value
一,select的onchange事件获取不了option的value是当你使用JQ($("#xxx").val())方法的获取的值一直提示undefined 二,解决方法: va ...
-
SQL入门之条件表达式
where子句和having子句主要是用来筛选符合条件的元组,其后紧跟的即为条件表达式. 0.and, or条件的连接 用法和一般编程语言一样,主要用于条件的拼接.and两边都为真,则结果为真.or两 ...
-
ES进阶--01
第2节结构化搜索_在案例中实战使用term filter来搜索数据 课程大纲 1.根据用户ID.是否隐藏.帖子ID.发帖日期来搜索帖子 (1)插入一些测试帖子数据 POST /forum/articl ...
-
SPFA找最大比例环
SPFA找最大比例环 ans=Σ点权/Σ边权 所以 可以变式为 Σ边权*ans-Σ点权=0 要找出最大的ans 可以二分 边权值变为 目的地点权-ans*边权 检查是否有负环 有则可以更优 #incl ...
-
Unity3D RTS游戏中帧同步实现
帧同步技术是早期RTS游戏常用的一种同步技术,本篇文章要给大家介绍的是RTX游戏中帧同步实现,帧同步是一种前后端数据同步的方式,一般应用于对实时性要求很高的网络游戏,想要了解更多帧同步的知识,继续往下 ...