32位4GLinux虚拟地址空间分布
每个程序在运行时,操作系统都会给它分配一个与CPU位数有关的虚拟地址空间,以32位系统为例:其中低3G为用户空间,是供用户的应用程序执行的,高1G为内核空间,是供内核代码运行的;每一个进程的用户控件都是独立的,所有进程的内核空间都是共享的。
虚拟地址空间的分配图:
用户空间:
用户空间依次为:
1、0x0000 0000 - 0x0804 8000 这128M是禁止访问的,操作系统在加载程序的时候都是从0x0804 8000开始加载的;
2、.text段存放指令;
3、.data段存放已初始化并且初始化不为0的数据;
4、.bss段存放未初始化或者初始化为0的数据;
5、接下来是堆区空间,在堆还没有被申请的时候,为堆区预留的空间称作空洞;
6、如果程序中有使用到库函数,那么在堆区和栈区中间存放共享库;
7、在共享库的高地址方向就是提供函数运行的.stack栈区;
8、栈区上方(栈的高地址方向)存放命令行参数和环境变量;
.text,.data,.bss在程序运行起来之后是固定不变的。程序在运行起来的时候还没有堆,执行到malloc或者new的时候,才会给它分配堆,程序运行起来必需的内存是代码段,数据段还有栈
指令和数据
用任何语言写代码,无非就产生了两种东西,数据和指令。
(1)局部变量属于指令;
(2)全局变量,静态全局变量,静态局部变量属于数据
int gdata1 = 10; //数据
int gdata2 = 0; //数据 强符号
int gdata3; //数据
static int gdata4 = 5; //数据
static int gdata5 = 0; //数据
static int gdata6; //数据
int main() //指令
{
int a = 8; //指令
int b = 0; //指令
int c; //指令
static int d = 6; //数据
static int e = 0; //数据
static int f; //数据
retrun 0; //指令
}
内核空间:
内核空间分为三部分:
1、低16M,ZONE_DMA直接访问内存;
2、中间的892M:ZONE_NORMAL;
3、高的128M:ZONE_HIGHMEM高端内存;
补充:
1、代码节:该段包含了供CPU执行的机器码指令(.text节)
2、数据节:该段包含了供CPU操作的数据。通常来说,初始化数据(.data节)、未初始化数据(.bss节)和只读数据(.rdata节)会保存在分离的节中。
3、堆:动态内存分配的区域
4、栈:为各个函数提供独立的存储空间
5、最上层部分属于内核区域,特定进程的环境变量就存放在该区域