这里写目录标题
虚拟地址空间-内核区-用户区
32位会分配一个地址空间4G的。2^32 == 4G
0-3G的用户区,3-4G内核区。
内核区–PCB进程控制块-进程管理
PCB进程控制块里面有一个文件描述符的表。 其实是一个数组-映射到一个文件,这个数组的大小是一个0-1023。每一个位置,都能代表打开一个文件,当前有一个进程,这个进程就能打开1024-3个文件。
前三个文件描述符默认是被打开的:
标准输入:STDIN_FILENO
标准输出:
标准错误:
总占用最小的文件描述符。
文件描述符就是一个整型数
0-3G的用户区
1、可执行程序a.out执行了,操作系统就会给程序分配出一块虚拟地址空间。在0-3G中,
ELF格式
linux下可执行文件,ELF格式。
file app//查看文件格式
可以得到,文件的格式ELF,是一个可执行文件。
例如:查看.c文件,得到是C的一个源文件,是一个ASCII码的格式的文本文件。
ELF格式主要包含三个段:
.text(代码段,二进制机器指令)a.out的源代码
.bss(未初始化全局变量)
.data(已初始化全局变量)
全局变量 = 0;//分到未初始化
c语言中,全局变量和局部静态变量是存储在静态存储区的,他们在分配的时候都被系统默认初始化为0;而局部自动变量是在栈上分配内存的,如果不对它们进行初始化,那么他们可能是任意的随机值。
#include <iostream>
using namespace std;
int b;
int main() {
int a = 22;
cout << a << endl << b;
return 0;
}
22
0
NULL对应的地址就是最下面的部分。
局部变量-栈空间
栈空间分配地址是向下增长的。
new或者meloc 给指针分配地址空间
是从下往上的分配
共享库,动态库
调用了一个C标准函数,比如说fread,fwrite
调用的都是一些动态库,拿到的不是真正的源代码,是提供好的动态库。
比如说:libc.so中封装的就是c标准库函数,那么在调用fread,fwrite等函数的时候就会加载libc.so库到动态库里面,再加载到共享区。
在共享区加载的时候,共享区哪空闲就会加载到哪里。所以起始位置是不定的,所以生成动态库的时候,**就只能生成与位置无关的代码。也就是相对地址。**例如:位移10个bit,到共享库中代码的位置。就能找到加法运算的函数,此处就是相对地址。
静态库 a.out
静态库被打包到a.out中,那个代码就直接放到代码段了。
命令行参数
环境变量
虚拟地址空间:
虚拟地址空间就是程序启动之后,在硬盘上会有一个虚拟内存分配出来。实际上用来多大的空间,才少多少空间。
虚拟地址,虚拟地址空间, 交换分区
1.虚拟内存是内存管理的一种方式, 它在磁盘上划分出一块空间由操作系统管理,当物理内存耗尽是充当物理内存来使用。它将多个物理内存碎片和部分磁盘空间重定义为连续的地址空间,以此让程序认为自己拥有连续可用的内存。当物理内存不足时,操作系统会将处于不活动状态的程序以及它们的数据全部交换到磁盘上来释放物理内存,以供其它程序使用。
**2.虚拟地址空间:在多任务操作系统中,每个进程都运行在属于自己的内存沙盘中,这个沙盘就是虚拟地址空间(virtual address space)。**虚拟地址空间由内核空间(kernel space)和用户模式空间(user mode space)两部分组成。
虚拟地址会通过页表(page table)映射到物理内存,页表由操作系统维护并被处理器引用,每个进程都有自己的页表。内核空间在页表中拥有较高特权级,因此用户态程序试图访问这些页是会导致一个页错误(page fault)。其中内核空间是持续存在的,并且在所有进程中都映射到同样的物理内存。与此相反,用户模式空间的映射随进程切换的发生而不断变化。
3.交换分区:在物理内存满时, 如果还需要内存资源,内核 则把物理内存中非活动的页面放到交换分区中。