1,为何内存须要分段和分页机制?linux
早起的计算机中,程序都是直接运行在物理内存上的。这样作有几个问题:windows
1)地址空间不隔离,计算机的安全性和稳定性没有办法保证,因为全部的程序均可以访问物理内存,恶意的程序能够很容易修改其余程序的内容,达到破坏的目的。缓存
2)内存使用效率低,当前执行的程序(列入进程A)必须被整个装载到内存中执行,若是须要执行另外一个程序时,发现内存空间不足,则须要将进程A的数据总体换出到磁盘。安全
3)程序运行的地址不肯定函数
为了解决上述的三个问题,引入了虚拟地址、分段和分页的概念。操作系统
有了虚拟地址,每一个进程都拥有本身独立的虚拟地址空间,而且结合分段技术,不一样进程的虚拟地址呗映射到不一样的物理地址,彼此之间不重叠,地址空间不隔离的问题就被解决了。线程
分页的基本思路是将内存分红固定大小的页,每一页的大小有硬件或者操做系统来决定。目前几乎所欲的PC机上的操做系统都是4KB大小的页。分页机制至关于增长了内存使用的的颗粒度,在内存换进换出的时候效率更高。调试
2,不一样的进程共享哪些资源?一个进程内的不一样线程之间共享哪些资源?进程
1)内存
2)线程私有:栈(局部变量、函数参数),TLS数据、寄存器。线程共享:全局变量、堆、静态变量、程序代码、打开的文件及信号。
3,线程安全机制
1)原子操做
2)信号量
3)互斥量
4)临界区
5)读写锁
6)条件变量
7)可重入函数
8*)CPU的乱序执行,barrier
4,编译和连接
1)预编译:gcc -E hello.c -o hello.i
2)编译:产生汇编代码文件。gcc -S hello.i -o hello.s
3)汇编:将汇编指令转变为二进制的机器指令。gcc -c hello.s -o hello.o或者as hello.s -o hello.o
4)连接:ld命令
5,目标文件
目标文件就是源代码编译后但未进行连接的那些中间文件(windows下的.obj和linux下的.o),它和可执行文件的内容与结构很类似,因此通常跟可执行文件采用相同的格式存储(windows PE-COFF和linux下的ELF)
目标文件中的内容包括编译后代码、数据、符号表、调试信息等。
*程序和指令分开存放有什么好处?1)指令区域只读,安全。2)cache的使用有助于提升CPU的缓存命中率。3)程序共享,运行同一个程序的多个副本时,只需一份代码
.bss段:不占用磁盘空间,存放静态变量和未初始化的全局变量.
.data段:初始化的全局变量
.text:代码段
.rodata:const变量和字符串常量
自定义段:
__attribute__ ((section("FOO"))) int global = 42;
__attribute__ ((section("BAR"))) void foo() {}
6,静态连接
1)ld命令
2)连接时空间和地址如何分配?不一样目标文件的.text、.data、.bss等段如何合并?
连接以前,虚拟地址尚未被分配,目标文件代码段的起始地址以0x00000000开始,等到连接中的空间分配完成后,各个函数才会肯定本身在虚拟地址空间中的位置。linux中的ELF可执行文件默认从地址0x08048000开始分配。
第十章、内存
1.用以维护函数调用的上下文,一般在用户空间的最高地址处分配,经过有数兆字节的大小。