从计算机的示例谈起:
远古的程序开发:直接操作物理内存
CPU指令的操作数直接使用实地址(实际内存地址)
程序员拥有绝对的权利(利用cpu指哪打哪)
绝对的权利带来的问题:
1难以重定位:程序每次都需要同样地址的内存执行。
有的程序用了开头和结尾,当在别的电脑上运行后,512k内存编写的程序用了开头32k,结尾8k,在256内存的设备上就不能执行了。
2给多道程序设计带来障碍:A程序和外设打交道,B程序也运行运算
A程序和B程序有内存重叠的话,就不能并行执行了。不管内存多大,但凡一个字节被其它程序占用都无法执行。
于是:出现了
cpu历史的里程碑-8086
当时地址线宽度为20位,可访问1M内存空间。
引入[段地址:偏移地址] 的内存访问方式:8086的段寄存器和和通用寄存器为16位,单个寄存器寻址最多访问64k的内存空间。需要两个寄存器配合,完成所有内存空间的访问。
发生冲突时改一下段地址就可以,不用改所有的地址了。
深入解析 [段地址:偏移地址]:
硬件所做的工作:
段地址左移4位,构成20位的基地址(起始地址)
基地址+偏移地址=实地址
对于开发者的意义:
更有效的划分内存的功能(数据段,代码段等)
当出现程序地址冲突时,通过修改段地址解决冲突。
示例:
mov ax, [0x1234] ;实地址:(ds<<4)+0x1234
mov ax, [es:0x1234] ; 实地址:(es<<4)+0x1234
有趣的问题:
[段地址:偏移地址] 能访问的最大地址为 0xFFFF:0xFFFF,即:10FFEF;超过了1MB的空间,cpu如何处理?
8086中的高端地址区(High Memory Area)
0xFFFF: 0xFFFF
-->0xFFFF0+0xFFFF
-->0xFFFF0+(0xF+0xFFF0)
-->(0xFFFF0+0xF)+0xFFF0 ==>HMA
HMA: [0x100000, 0x10FFEF]
8086的处理方式:
由于8086只有20位地址线,因此最高位被丢弃(溢出)!
0xFFFF : 0xFFFF==>10000111111111101111(21位)=>回卷0xFFEF
再谈8086历史:
8086在当时是非常成功的一款产品。因此,拥有一大批的开发者和应用程序。各种基于8086程序设计的技术得到了发展。不幸的是,各种不规范的开发方式也产生了。
8086时期应用程序中的问题:
1MB内存完全不够用(内存在任何时期都不够用)
开发者在程序中大量使用内存回卷技术(HMA地址被使用)
应用程序之间没有界限,相互之间随意干扰:A程序可以随意访问B程序中的数据。c程序可以修改系统调度程序的指令。
思考:8086程序中问题的本质是什么?
80286的登场:
8086已经有那么多应用程序了,所以必须兼容
加大内存容量,增加地址线数量(24位:支持16M的内存)
[段地址 :偏移地址] 的方式可以强化一下:
为每个段提供更多属性(如:范围,特权级,等)
为每个段的定义提供固定方式。
80286的兼容性:
默认情况下完全兼容8086的运行方式(实模式)
默认可直接访问1MB的内存空间。
通过特殊的方式访问1MB+的内存空间。
这个特殊的方式指的是什么??
80286之后的工作模式:
实模式:任何内存随意访问
兼容8086的工作模式
实地址=(段寄存器<<4)+偏移地址
任意内存随意访问
保护模式:
新的工作模式
内存地址=段起始地址+偏移地址
每段增加各种属性描述,保证安全性
初始保护模式:
每一段内存得拥有一个属性定义(描述符Descriptor)
所有段的属性定义构成一张表(描述符表Descriptor Table)
段寄存器保存的是属性定义在表中的索引(选择子Selector)
描述符(Descriptor)的内存结构:8个字节
段界限来防止回卷,8086不推荐使用回卷。定义段内偏移地址的最大值来防止回卷。
段基址为什么要分三个部分? 历史原因。拼接是硬件来处理的。
在内存中,每个段描述符8个字节。使用特殊寄存器来装段描述符在内存中的起始地址。每一个段描述符都是一段内存的定义。
选择子(Selector)的结构:
0-15 =>段描述符在段描述符表中的位置。0-1 RPL(特权级)。 2 TI(两个描述符表选择)。
说明:
RPL:请求者特权级标识,通过特权级判断是否可以访问对应段。
TI: 表示当前选择子所属的描述符表(0-GDT,1-LDT)。
进入保护模式的方式:
1、定义描述符表。
2、打开A20地址线。8086(0-19)
3、加载描述符表。
4、通知CPU进入保护模式。
小结:
[ 段地址:偏移地址] 的寻址方式 解决了早期程序重定位难的问题。
8086实模式下的程序无法保证安全性。
80286中提出了保护模式,加强了内存段的安全性。
处于兼容性的考虑,80286之后的处理器都有2种工作模式。
处理器需要特定的设置步骤才能进入保护模式,默认为实模式。