对内存的思考(C专家编程)

伟大的比尔盖茨曾经失言:

640K ought to be enough for everybody — Bill Gates 1981

从一块芯片说起—Intel 80x86系列

现代的Intel处理器可以追溯到最早期的Intel芯片。随着顾客对芯片的使用越来越复杂,从单纯的计算器到统计、制表、游戏,他们对芯片的要求也越来越高。1978年中Intel推出第一款16位微处理器Intel 8086,随后于1979年推出8088。这是一款划时代意义的处理器,它采用16位数据总线,20位外部总线,物理寻址空间达到1M。注意8086的数据总线与外部地址总线数目并不相同即内部数据总线传输的16位数据只能表示$2^{16}$个字节(Byte),而外部地址总线传输20位数据则可表示$2^{20}$个字节(Byte),即微处理器中单独一个(16位,2字节),不能表示所有的地址空间,Intel为了解决这个问题发明了分段机制。

8086的封装采用40引脚的双列直插(dual in-line),数据总线与地址总线复用了前16个引脚。16位的I/O地址,因此独立的I/O寻址空间为64KiB (即216 = 65536).由于8086内部的地址寄存器是16 位宽,因而最大线性寻址空间为64 KB。使用超过64 KB内存空间的程序设计时,需要调整段寄存器(segment registers)。即段寄存器保存段编号,而段寄存器也是16位,当计算物理地址时将段寄存器中的值向左移4位然后与16位偏移量(offset)相加得到实际的20位物理地址。这种机制保证微处理器对存储器的充分寻址。

8086微处理器被搭载在IBM 成功的个人电脑IBM PC XT上,随着上世纪80年代PC机的浪潮,8086为Intel最为成功的微处理器之一,不仅销量大同时伴随着因此而产生的各类软件系统。其中就有一个鼎鼎有名的软件——Microsoft Disk Operating System(MS DOS)。

既然采用了这个基本的地址模型,后续的80x86处理器不得不延续这种做法,否则就会导致不兼容。我们无法知道IBM在1979年选择Intel 8088(一种与8086同代的处理器)作为它新开发的PC的处理器的确切原因,毕竟从技术上说,当时有许多公司可以提供更为出色的方案,如Motorola和National Semiconductor。由于选择了Intel的芯片,IBM帮助Intel在接下来的数十年里财源滚滚,就像IBM选择了Microsoft的MS-DOS作为PC的操作系统从而使Microsoft飞黄腾达一样。

用于最初的IBM PC的8088处理器只是8086的廉价版本,它允许当时大量存在的支持8位的芯片继续使用。此后对80x86处理器的升级都体现在“更小、更快、更便宜以及更多指令”上,例如80186增加了10条并不是很重要的指令。80286差不多就是80186(内置了一些外设端口支持),但它第一次试图扩展内存地址空间。他把内存控制器移到处理器外部,并提供了一种野心勃勃的内存模式,称为虚拟模式 在虚拟模式中,段寄存器不在于偏移地址相加,而是作为一个存放实际段地址的表提供索引。这种地址模式也成为保护模式(protected mode) ,它依然是16位的。MS-Windows就使用286的保护模式作为它的标准地址模式。这些处理器卖的并没有8086系列成功,直到1985年Intel推出Intel 80386处理器。80386在80286的基础上增加了2种新的地址模式:32位的保护模式和虚拟的8086模式。Microsoft的旗舰产品Windows NT操作系统(Windows 10就属于Windows NT 10.0)和增强模式下的Windows都采用了32位的保护模式。而另一种内存模式,虚拟的8086模式则可以创建一种内存空间为1MB的8086虚拟机。几个虚拟机可以同时运行从而支持MS-DOS的虚拟多任务系统。

Intel 80x86内存模型以及它的工作原理

在Intel 80x86内存模型中,段是内存模型设计的结果,在80x86的内存模型中,各处理器的地址空间并不相同,但它们都被分割成以64KB为单位的区域,每个这样的区域就被称为。8086中的段是一块64KB的内存区域,由一个段寄存器所指向。内存地址的形成:取得段寄存器的值,左移4位(相当于乘上16),然后与16位的偏移地址(它表示段内的地址)相加就得到20位的最终地址。

MS-DOS的640K限制缘何而来

在MS-DOS下运行的应用程序都会面临一个严峻的内存限制,那就是可用内存只有640KB。这个限制源于Intel 8086这个最初的DOS机器的最大地址范围。8086支持1MB的内存。之所以只能使用640KB是因为某些段(每个64KB)必须予以保留,供系统所用。

段 保存用于

F0000到FFFFF 64KB,永久性的ROM区域BIOS、诊断信息

D0000到EFFFF 128KB,用于ROM存储区域

C0000到CFFFF 64KB,用于BIOS扩展

B0000到BFFFF 64KB,用于常规性的内存显示

A0000到AFFFF 64KB,用于显示内存扩展

其余

00000到9FFFF 640KB,用于应用程序

你可能感兴趣的:(内存,思考)