前言

 

前一篇我们介绍了内存管理中的分页试内存管理,分页的主要作用就是使得每个进程有一个独立的,完整的内存空间,通过虚拟内存技术,使得程序可以在较小的内存上运行,而进程之间内存空间相互独立,提高了安全性。这一篇将主要介绍内存管理中分段管理,以及两种的结合,也是目前计算机普遍采用的段页式内存管理。这也直接决定了的后面程序的编译,加载以及允许时的内存布局。

 

 

 

1. 内存分段

 

 

1.1 为什么分段?

 

 

在x86-16体系中,为了解决16位寄存器对20位地址线的寻址问题,引入了分段式内存管理。而CPU则使用CS,DS,ES,SS等寄存器来保存程序的段首地址。当CPU执行指令需要访问内存时,只会送出段内的偏移地址,而通过指令的类型类确定访问那一个段寄存器。具体可以参考:计算机原理学习(5)– x86-16 CPU和内存管理

 

到了IA-32,Intel引入了保护模式,所以在IA-32中为了保持兼容性,所以同样支持内存分段管理。另外我们讨论过了内存分页,页面中包含了程序的代码,数据等信息,它们都有各自的地址。这些地址是在编译的时候就确定的,因为每个进程都有独立完整的内存空间,只需要把页和物理页映射就能运行,所以这个地址是可以在编译时就决定的。在编译时,编译器会等程序进行语法词法等分析,在编译过程中会建立许多的表,来确定代码和变量的虚拟地址:

  • 被保存起来供打印清单的源程序正文;
  • 符号表,包含变量的名字和属性;
  • 包含所有用到的整形和浮点型数据的表;
  • 语法分析树,包括程序语法分析的结果;
  • 编译器内部过程调用的堆栈。

前面4张表会随着编译的进行不断增大,而堆栈的数据也会变化,现在的问题就是,每一张表的大小都不确定,那么如何指定每一张表在虚拟内存空间的地址呢?

继续阅读

0