李超

cc编程笔记本。

  博客园 :: 首页 :: 博问 :: 闪存 :: 新随笔 :: 联系 :: 订阅 订阅 :: 管理 ::
存储器的管理模式
intel公司的80x86系列的CPU对内存的管理采用的是内存分段的方式。

1. 存储器的分段
计算机的内存管理单元是以“字节”为最小单位进行线性编址的,字节是80x86CPU对内存管理的基元。为了标识每个存储单元,就给每个存储单元规定一个编号,该编号就是内存单元的物理地址。
存储单元的物理地址是一个16位的二进制数,物理地址通常采用16进制书写。

16位CPU内部拥有20根地址线,它的寻址范围就是2的20次方,也就是1M的内存空间。
但是16位CPU存放存储单元偏移量的寄存器(IP,SP,BP,SI,DI,BX)的编码范围仅为:00000H - 0FFFFH,也就是只能访问65536个存储单元,64K。
为了能够访问1M的内存空间,CPU就采用了内存分段的管理模式,并且在CPU内部加入了段寄存器。
16位CPU把内存空间分为若干个逻辑段,每个逻辑段的要求如下:
 1) 逻辑段的起始地址(段地址)必须是16的倍数,即最后4个二进制位必须全为0。
 2) 逻辑段的最大容量为64K,这由16位寄存器的寻址空间所决定。

2. 物理地址的形成方式
由于段地址必须是16的倍数,所以值的一般形式为XXXX0H,即前16位二进制位是变化的,后四位是固定的0,鉴于段地址的这种特性,可以只保存前16位二进制位来保存整个段地址,所以每次使用时要用段寄存器左移补4个0(乘以16)来得到实际的段地址。
在确定了某个存储单元所属的内存段后,我们也只是知道该存储单元所属的范围(段地址 到 段地址+65536),如果想确定内存单元的具体位置,还必须知道该单元距离该段地址有多远。我们通常把这个存储单元的实际地址和段地址之间的范围称为段内偏移,也称为有效地址(EF-Effective Address)偏移量(Offset),有了段地址和偏移量,就可以唯一的确定某一内存单元在存储器的具体位置。

存储单元的逻辑地址分为两个部分 段地址:偏移量
由逻辑地址得到物理地址(PA - Physical Address)的公式为: PA = 段寄存器的值 * 16 + 偏移量(为什么要乘16,因为段寄存器没有保存段地址的后4位,所以要*16,或者用左移4位)。
实际在计算的时候,是用  PA = 段寄存器 << 4 + 偏移量。  因为左移操作比乘法操作快。

3. 段寄存器的引用
段寄存器就是为了对内存进行分段管理而增加的,16位CPU有四个段寄存器(而1M内存可分成16个互不重复的段),所以程序可同时访问四个不同含义的段。
 1) CS + IP 代码段的访问,指向用于存放程序的内存段,寄存器IP指向下条要执行的指令在CS段的偏移量,用这两个寄存器就可以得到一个内存物理地址,该地址存放着一条要执行的指令: CS << 4 + IP。
 2) SS + BP / SS + SP 堆栈段的访问,指向用于存放堆栈的内存段,SP一直指向栈顶,可以通过SS和SP两个寄存器直接访问栈顶单元的内存物理位置,另外,当偏移量使用了指针寄存器BP,缺省的段寄存器也是SS,并且可以用BP访问整个堆栈,而不只是访问栈顶数据。(这是绕过压栈弹栈机制直接操作堆栈段的方式)
 3) DS + BX  数据段的访问。 DS中的值左移四位得到附加段起始地址,再加上BX中的偏移量,得到一个存储单元的物理地址。
 4) ES + BX  附加段的访问。 ES中的值左移四位得到附加段起始地址,再加上BX中的偏移量,得到一个存储单元的物理地址。


段寄存器和指针寄存器的引用关系:
访问存储器方式 缺省的段寄存器 可选用的段寄存器 偏移量
取指令 CS   IP
堆栈操作 SS   SP
一般取操作数 DS CS、ES、SS 有效地址
串操作

源操作数

DS CS、ES、SS SI

目标操作数

ES   DI

使用指针寄存器BP

SS CS、DS、ES 有效地址
16位CPU在段寄存器的引用方面有如下约定:
 1). 取指令所用的段寄存器和偏移量一定用CS和IP
 2). 堆栈操作所使用的段寄存器和偏移量一定用SS和SP
 3). 串操作的目标操作数所用的寄存器和偏移量一定是ES和DI
 4). 其他情况 段寄存器除了默认引用的寄存器外 还可以强行改变为其他段寄存器。

4. 存储单元的内容

上面三章内容已经让我们知道内存单元物理地址的计算方法,使我们很容易的指定我们要访问的存储单元,但是我们还要知道存储单元的内容是如何存放的。
存储单元所存放的二进制信息通常称为该存储单元的内容或值,并规定:
 1) 一个字节的内容是该字节单元内存放的二进制信息
 2) 一个字的内容是该字地址所指向的单元及其后继一个单元的内容拼接而成
 3) 一个双字的内容是该双字地址所指向的单元及其后继三个单元的内容拼接而成

在拼接字单元时 我们按高高低低的原则来处理,即高存储单元(地址大的存储单元)的值是“字内容”的高8位,低存储单元(地址小的存储单元)的值是“字内容”的低8位。

5. 32位微机的内存管理模式
32位pc的内存管理仍然采用“分段”的管理模式,存储器的逻辑地址同样由段地址和偏移量两部分组成,32位pc的内存管理和16位pc的内存管理有相同之处也有不同之处,因为32位pc采用了两种不同的工作方式:实方式和保护方式。
(1) 物理地址的计算方式
 1) 实模式下
   在实模式下段地址仍然都是16的倍数,每个段的最大容量仍然是64K,段寄存器的值*16是起始地址,存储单元的物理地址仍然是段地址 + 段内偏移量,在实模式下,32位微机的内存管理与16位微机是相一致的。
 2) 保护模式下
   段地址可以长达32位,其值可以不再是16的倍数,每个段的最大容量可达4G,段寄存器的值是表示段地址的“选择器”(Selector),用该“选择器”可以从内存中得到一个32位的段地址,存储单元的物理地址就是该段地址加上段内偏移量,这与16位微机的物理地址计算方式完全不同。
(2) 段寄存器的引用
 32位cpu内有6个段寄存器,程序在某一时刻可以同时访问6个不同的段。其段地址的值在不同的方式下具有不同的含义:
 1) 在实方式下 段寄存器的值*16就是段地址
 2) 在保护方式下 段寄存器的值是一个选择器,可以间接指出一个32位的段地址。

代码段寄存器:32位Pc在取指令的时候,系统自动引用CS和EIP来取出下条指令,在实方式下,由于段的最大容量不超过64K,所以EIP的高16位全部是0,也就是说在实方式下EIP与IP是相同的。

堆栈段寄存器:32位Pc在访问堆栈段的时候,总是引用堆栈段寄存器SS。但在不同的方式下堆栈指针有所不同:
 1)在实方式下 32位Pc把ESP的低16位SP作为指向堆栈的指针,所以我们可以认为栈顶单元是用SS和SP寄存器共同指定的,与16位Pc模式下访问栈顶单元的方法一致。
 2)在保护方式下,堆栈指针可以用32位的ESP和16位的SP

数据段寄存器:DS是主要的数据段寄存器,通常他是访问堆栈以外数据的主要寄存器,在某些串操作中,其目的操作数的段寄存器被指定为ES是一个例外。
另外 段寄存器CS,SS,ES,FS和GS也都可以作为访问数据时的寄存器,但它们必须用段超越前缀的方式直接在指令中写出,这种方式会增加指令的长度,指令的执行时间也有所延长。
一般情况下,程序频繁使用的数据段用DS来指向,不太常用的数据段可用ES,FS和GS来指向。
(3) 存储单元的内容
32位微机存储单元内容的存储格式与16位微机完全一致,也都用“高高低低”的原则存放数据。
posted on 2008-02-25 10:44  coderlee  阅读(1730)  评论(3编辑  收藏  举报