进程虚拟地址空间
大约 3 分钟
任何的编程语言都会产生两种东西:指令和数据。c++代码编译链接之后产生一个可执行文件***.exe
存储在磁盘上,运行时会把程序从磁盘加载到内存(虚拟)中,
产生几个问题:
- 运行时把可执行程序的哪些东西加载到内存中?
- 加载到内存后是如何存放的?
- 内存空间有没有区域划分?划分后是什么样的??
前提条件:
虚拟如何理解?
存在,能看见 是物理的
存在, 看不见 是透明的
不存在, 看得见 是虚拟的
不存在, 看不见 被删除了
linux系统会为当前进程分配一个2^32大小的空间

0x00000000到0x08048000是系统预留的空间
,不可访问,如访问空指针时程序会崩溃
.text
段:代码段,存放指令
.rodata
:只读数据段,常量就存放在此,例如const char *p = “hello”;//p在栈上,而“hello”在只读数据段上,因为这个是字符串常量
.data
:数据段,存放已经初始化且初始化不为0的全局变量/静态变量
.bss
:数据段,存放初始化为0和未初始化的全局变量/静态变量,内核会将此数据段都置0
.heap
:堆区,当程序运行时,new或malloc后才会分配堆内存,由低地址向高地址增长,程序员自己管理内存
.dll,*so
:加载共享库,也就是动态链接库,window下是.dll,linux下是so
.stack
:函数运行或产生线程时,每一个函数或线程独有的栈空间,由高地址向低地址增长
命令行参数,环境变量
:命令行参数如main函数传参,环境变量如搜索头文件或库文件时默认的路径
内核空间
:
- ZONE_DMA:ZONE“区域的意思”,约16M
- ZONE_BORMAL:约800多M,存放进程控制块(PCB块,task_struct)、内核空间的线程、内核函数运行时所依赖的栈空间……
- ZONE_HIGHMEN:高地址物理内存,做内存映射用的
#include<bits/stdc++.h>
#include<iostream>
using namespace std;
int a=7;
int b=0;
int c;
static int sa=8;
static int sb=0;
static int sc;
int main(){
int d=10; //move dword ptr[d],0AH
//move dword ptr[esp],0AH
int e=0;
int f;
static int sd=10;
static int se=0;
static int sf;
cout<<c<<" "<<sc<<" "<<f<<" "<<sf;
}
全局变量都是数据,放在数据段(a,sa在.data段 b,c,sb,sc在.bss段)
🍊声名**,运行时会在栈上开辟空间存储变量值,**
cout << f << c << endl
f
不为0、c
为0- ,e在.data,f,g在.bss
- ,匿名管道通信就是在内核空间划分一道地址空间进行通信

为什么进程间通信比较困难,主要原因是用户空间是私有的,只要内核空间是共享的