进程虚拟地址空间及划分

任何的编程语言编译所产生的只有 指令数据


在Windows操作系统/Linux操作系统下,C++文件编译链接之后会产生一个.exe/.out文件,该文件存储在磁盘上。

CPU运行程序,需要将文件加载到内存中,但肯定不是直接加载到实际的物理内存中,而是加载到进程的虚拟地址空间。x86 32位Linux环境下,Linux内核会给当前进程分配一块2^32大小的空间,大小为4G。

虚拟就是:

        它存在,你能看得见,它是物理的

        它存在,你看不见,它是透明的

        它不存在,你却看得见,它是虚拟的

        它不存在,你也看不见,它被删除了

虚拟地址空间不是物理内存,本质底层就是内核所创建的一系列数据结构。

以下是进程虚拟地址空间划分图:


接下来对每一个划分部分进行说明:(用户空间

1、 0x00000000-0x08048000:这一段是不能被访问的,如果访问,程序会奔溃。

2、.text(代码段)存放指令,.rodata只读数据段(常量区)const char *p="hello world!"。

3、.data已初始化数据段。

4、.bss已初始化数据段或已初始化为零,内核会将.bss段的数据全部置为0。

5、堆内存,使用new/malloc进行申请,从上往下。

6、加载共享库,Windows下.dll,linux下.so文件。

7、栈空间,函数运行在栈上开辟空间,每个线程私有的线程栈。从下往上进行增长。

8、例如执行指令:./a.out 192.168.1.100 9090 。该段用来存储程序运行时的命令行参数和环境变量。


#include <iostream>
int gdata1 = 10;
int gdata2= 0;
int gdata3;

static int gdata4 = 11;
static int gdata5 = 0;
static int gdata6;

int main()
{
    int a = 12;
    int b = 0;
    int c;

    static int e = 13;
    static int f = 0;
    static int g;
    return 0;
}

所以:

gdata1、gdata4已初始化且不为零,存储在.data段。

gdata2、gdata3、gdata5、gdata6未初始化或者初始化为零,存储在.bss段。

而对于main()函数中的局部变量,有以下分析:

int a = 12;  mov dword ptr[a],0Ch

int b = 0;

int c;

这三者编译生成指令,指令存放在.text段。程序运行时,指令会在栈上开辟空间用来临时存储局部变量。

而e、f、g这三个静态局部变量分别存储在.data、.bss、.bss,但是程序启动的时候并不会进行初始化,是第一次运行到的时候才进行初始化。


 每个进程的用户空间是私有的,但内核空间是共享的!!!

进程与进程之间通信难是因为各个进程的用户空间是私有的,所以可以通过管道来进行通信。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值