程序员的自我修养笔记

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.用以维护函数调用的上下文,一般在用户空间的最高地址处分配,经过有数兆字节的大小。

相关文章
相关标签/搜索