博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
linux 内核内存加载映射
阅读量:3811 次
发布时间:2019-05-22

本文共 2599 字,大约阅读时间需要 8 分钟。

linux 内核内存布局(以64位系统为例) 

       64位系统理论可寻址范围位2的64次方,但实际一般用不到,故linux的可寻址范围位2的48次方;其中128T为内核空间,128T为用户空间。编译器把源程序编译为各个段(Segment),段是由一个或多个节(section)组成。linux下可执行文件是ELF格式,因此可以通过以下命令查看各个段或节的内存地址:

readelf -S memoryCkeck   #查看可执行程序由多少个节以及每个节的地址readelf -l memoryCheck   #查看可执行程序头的地址以及大小,其中两个LOAD头是内存加载映射的重点size memoryCheck    # 查看程序BSS,Data,Text各个段的大小cat /proc/${pid}/maps  #同样可以查看程序的内存映射,其中没有名字的为匿名映射,一行为一个vm_area_struct

注:ELF格式的详细解析可以参考博文

平常理解的程序加载情况如图1所示,但实际操作系统加载时,操作系统不关心加载的内容,反而更加关心加载内容的权限。所以编译器会把权限相同的节会尽可能放在一起,故实际加载时的格局如如2所示:

                                                                                                 图1 

                                                                                        图2 

注:图中的.xxx即节的名称,查看ELF文件时可以看到;

实验验证内存映射情况

//memoryCheck.c#include 
#include
#include
/*查看进程中内存地址的分配*/int A; //全局变量未初始化int B = 0; //全局初始化为0的变量int C = 2; //全局初始化变量static int D; //全局静态未初始化变量static int E = 0; //全局静态初始化为0的变量static int F = 4; //全局静态初始化变量const int G = 5; //全局常亮const char H = 6;const char I = 7;int main(void){ int a; //局部未初始化变量 int b = 0; //局部初始化为0的变量 int c = 2; //局部初始化变量 static int d; //局部静态未初始化变量 static int e = 0; //局部静态初始化为0的变量 static int f = 4; //局部静初始化变量 const int g = 5; //局部常量 char char1[] = "abcde"; //局部字符串数组,保存在栈上 char *cptr = "123456"; //p在栈上,123456在常量区 int *heap = malloc(sizeof(int)*4); //堆 printf("PID is:%d\n\n",getpid()); printf("int A A_addr = %p\n",&A); printf("int B = 0 B_addr = %p\n",&B); printf("int C = 2 C_addr = %p\n",&C); printf("static int D D_addr = %p\n",&D); printf("static int E = 0 E_addr = %p\n",&E); printf("static int F = 4 F_addr = %p\n",&F); printf("const int G = 4 G_addr = %p\n",&G); printf("const char H = 6 H_addr = %p\n",&H); printf("const char I = 7 I_addr = %p\n",&I); printf("\n"); printf("int a a_addr = %p\n",&a); printf("int b = 0 b_addr = %p\n",&b); printf("int c = 2 c_addr = %p\n",&c); printf("static int d d_addr = %p\n",&d); printf("static int e = 0 e_addr = %p\n",&e); printf("static int f = 4 f_addr = %p\n",&f); printf("const int g = 5 g_addr = %p\n",&g); printf("\n"); printf("char char1[] = 'abcde'\t\t\tchar1_addr = %p\n",char1); printf("char char1[] = 'abcde'\t\t\t&char1_addr = %p\n",&char1); printf("char *cptr = '1'\t\t\tcptr_addr = %p\n",&cptr); printf("value of the cptr\t\t\tcptr_value = 0x%p\n",cptr); printf("value of %p\t\t\tvalue_0x%p = %d\n",cptr,cptr,*cptr); printf("int* heap = malloc(sizeof(int)*4)\theap__addr = %p\n",heap); printf("int* heap = malloc(sizeof(int)*4)\t&heap__addr = %p\n",&heap); pause(); /*程序结束运行后再回收堆内存,方便观察堆的地址*/ free(heap); return 0;}

 

转载地址:http://zoaxn.baihongyu.com/

你可能感兴趣的文章
Android View 事件分发机制 源码解析
查看>>
Android ViewGroup事件分发机制
查看>>
Android快速开发系列 10个常用工具类
查看>>
在线程中调用PJSIP中的呼叫出现提示注册线程pj_thread_register的解决方法
查看>>
MFC修改窗口客户区颜色
查看>>
MFC圆角矩形窗口
查看>>
android studio开发jni无法生成so文件
查看>>
Android酷炫实用的开源框架(UI框架)
查看>>
Android开源库集锦
查看>>
Android-ViewPagerIndicator使用方法
查看>>
Android基础入门教程——1.6 .9(九妹)图片怎么玩
查看>>
Android中Application类用法
查看>>
Android Studio导入第三方库(SlidingMenu)教程
查看>>
XUtils===XUtils3框架的基本使用方法(一)
查看>>
VC++6.0调试篇:定位临界区(critical section)导致的死锁
查看>>
windows下socket编程:区分shutdown()及closesocket()
查看>>
Android开发中常用ADB命令总结
查看>>
库的三种加载方法 显示加载 隐示加载 延迟加载
查看>>
VS2010安装包制作全过程图解
查看>>
duilib\utils\utils.h(251) : error C2504: “VARIANT”: 未定义基类
查看>>