程序员的自我修养笔记

1,为什么内存需要分段和分页机制?

早起的计算机中,程序都是直接运行在物理内存上的。这样做有几个问题:

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

 

posted @ 2014-07-08 18:32  idiotshi  阅读(234)  评论(0编辑  收藏  举报