HDWX86寄存器详解知识分享_第1页
HDWX86寄存器详解知识分享_第2页
HDWX86寄存器详解知识分享_第3页
HDWX86寄存器详解知识分享_第4页
HDWX86寄存器详解知识分享_第5页
已阅读5页,还剩59页未读 继续免费阅读

下载本文档

版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领

文档简介

1、Good is good, but better carries it.精益求精,善益求善。HDWX86寄存器详解寄存器目录HYPERLINKjavascript:void(0)隐藏HYPERLINK/view/6159.htmll1#1寄存器定义HYPERLINK/view/6159.htmll2#2寄存器用途HYPERLINK/view/6159.htmll3#3数据寄存器HYPERLINK/view/6159.htmll4#4寄存器分类英文名称:RegisterHYPERLINK/view/6159.htmll#编辑本段寄存器定义寄存器是HYPERLINK/view/14045.htmt

2、_blank中央处理器内的组成部份。寄存器是有限存贮容量的高速存贮部件,它们可用来暂存指令、数据和位址。在中央处理器的控制部件中,包含的寄存器有HYPERLINK/view/178142.htmt_blank指令寄存器(IR)和HYPERLINK/view/178145.htmt_blank程序计数器(PC)。在中央处理器的算术及逻辑部件中,包含的寄存器有HYPERLINK/view/471649.htmt_blank累加器(HYPERLINK/view/331459.htmt_blankACC)。寄存器是内存阶层中的最顶端,也是系统获得操作资料的最快速途径。寄存器通常都是以他们可以保存的位元

3、数量来估量,举例来说,一个“8位元寄存器”或“32位元寄存器”。寄存器现在都以寄存器档案的方式来实作,但是他们也可能使用单独的正反器、高速的核心内存、薄膜内存以及在数种机器上的其他方式来实作出来。寄存器通常都用来意指由一个指令之输出或输入可以直接索引到的暂存器群组。更适当的是称他们为“架构寄存器”。例如,x86指令及定义八个32位元寄存器的集合,但一个实作x86指令集的CPU可以包含比八个更多的寄存器。寄存器是CPU内部的元件,寄存器拥有非常高的读写速度,所以在寄存器之间的数据传送非常快。HYPERLINK/view/6159.htmll#编辑本段寄存器用途1.可将寄存器内的数据执行算术及逻辑

4、运算;2.存于寄存器内的地址可用来指向内存的某个位置,即寻址;3.可以用来读写数据到电脑的周边设备。HYPERLINK/view/6159.htmll#编辑本段数据寄存器8086有14个16位寄存器,这14个寄存器按其用途可分为(1)通用寄存器、(2)指令指针、(3)标志寄存器和(4)段寄存器等4类。(1)通用寄存器有8个,又可以分成2组,一组是数据寄存器(4个),另一组是指针寄存器及变址寄存器(4个).数据寄存器分为:AH&ALAX(accumulator):累加寄存器,常用于运算;在乘除等指令中指定用来存放操作数,另外,所有的I/O指令都使用这一寄存器与外界设备传送数据.BH&BLBX(b

5、ase):基址寄存器,常用于地址索引;CH&CLCX(count):计数寄存器,常用于计数;常用于保存计算值,如在移位指令,循环(loop)和串处理指令中用作隐含的计数器.DH&DLDX(data):数据寄存器,常用于数据传递。他们的特点是,这4个16位的寄存器可以分为高8位:AH,BH,CH,DH.以及低八位:AL,BL,CL,DL。这2组8位寄存器可以分别寻址,并单独使用。另一组是指针寄存器和变址寄存器,包括:SP(StackPointer):堆栈指针,与SS配合使用,可指向目前的堆栈位置;BP(BasePointer):基址指针寄存器,可用作SS的一个相对基址位置;SI(SourceIn

6、dex):源变址寄存器可用来存放相对于DS段之源变址指针;DI(DestinationIndex):目的变址寄存器,可用来存放相对于ES段之目的变址指针。这4个16位寄存器只能按16位进行存取操作,主要用来形成操作数的地址,用于堆栈操作和变址运算中计算操作数的有效地址。(2)指令指针IP(InstructionPointer)指令指针IP是一个16位专用寄存器,它指向当前需要取出的指令字节,当BIU从内存中取出一个指令字节后,IP就自动加1,指向下一个指令字节。注意,IP指向的是指令地址的段内地址偏移量,又称偏移地址(OffsetAddress)或有效地址(EA,EffectiveAddres

7、s)。(3)标志寄存器FR(FlagRegister)8086有一个18位的标志寄存器FR,在FR中有意义的有9位,其中6位是状态位,3位是控制位。OF:溢出标志位OF用于反映有符号数加减运算所得结果是否溢出。如果运算结果超过当前运算位数所能表示的范围,则称为溢出,OF的值被置为1,否则,OF的值被清为0。DF:方向标志DF位用来决定在串操作指令执行时有关指针寄存器发生调整的方向。IF:中断允许标志IF位用来决定CPU是否响应CPU外部的可屏蔽中断发出的中断请求。但不管该标志为何值,CPU都必须响应CPU外部的不可屏蔽中断所发出的中断请求,以及CPU内部产生的中断请求。具体规定如下:(1)、当

8、IF=1时,CPU可以响应CPU外部的可屏蔽中断发出的中断请求;(2)、当IF=0时,CPU不响应CPU外部的可屏蔽中断发出的中断请求。TF:跟踪标志TF。该标志可用于程序调试。TF标志没有专门的指令来设置或清楚。(1)如果TF=1,则CPU处于单步执行指令的工作方式,此时每执行完一条指令,就显示CPU内各个寄存器的当前值及CPU将要执行的下一条指令。(2)如果TF=0,则处于连续工作模式。SF:符号标志SF用来反映运算结果的符号位,它与运算结果的最高位相同。在微机系统中,有符号数采用补码表示法,所以,SF也就反映运算结果的正负号。运算结果为正数时,SF的值为0,否则其值为1。ZF:零标志ZF

9、用来反映运算结果是否为0。如果运算结果为0,则其值为1,否则其值为0。在判断运算结果是否为0时,可使用此标志位。AF:下列情况下,辅助进位标志AF的值被置为1,否则其值为0:(1)、在字操作时,发生低字节向高字节进位或借位时;(2)、在字节操作时,发生低4位向高4位进位或借位时。PF:奇偶标志PF用于反映运算结果中“1”的个数的奇偶性。如果“1”的个数为偶数,则PF的值为1,否则其值为0。CF:进位标志CF主要用来反映运算是否产生进位或借位。如果运算结果的最高位产生了一个进位或借位,那么,其值为1,否则其值为0。)4)段寄存器(SegmentRegister)为了运用所有的内存空间,8086设

10、定了四个段寄存器,专门用来保存段地址:CS(CodeSegment):代码段寄存器;DS(DataSegment):数据段寄存器;SS(StackSegment):堆栈段寄存器;ES(ExtraSegment):附加段寄存器。当一个程序要执行时,就要决定程序代码、数据和堆栈各要用到内存的哪些位置,通过设定段寄存器CS,DS,SS来指向这些起始位置。通常是将DS固定,而根据需要修改CS。所以,程序可以在可寻址空间小于64K的情况下被写成任意大小。所以,程序和其数据组合起来的大小,限制在DS所指的64K内,这就是COM文件不得大于64K的原因。8086以内存做为战场,用寄存器做为军事基地,以加速工

11、作。以上是8086寄存器的整体概况,自80386开始,PC进入32bit时代,其寻址方式,寄存器大小,功能等都发生了变化。=以下是80386的寄存器的一些资料=寄存器都是32-bits宽。A、通用寄存器下面介绍通用寄存器及其习惯用法。顾名思义,通用寄存器是那些你可以根据自己的意愿使用的寄存器,修改他们的值通常不会对计算机的运行造成很大的影响。通用寄存器最多的用途是计算。EAX:通用寄存器。相对其他寄存器,在进行运算方面比较常用。在保护模式中,也可以作为内存偏移指针(此时,DS作为段寄存器或选择器)EBX:通用寄存器。通常作为内存偏移指针使用(相对于EAX、ECX、EDX),DS是默认的段寄存器

12、或选择器。在保护模式中,同样可以起这个作用。ECX:通用寄存器。通常用于特定指令的计数。在保护模式中,也可以作为内存偏移指针(此时,DS作为寄存器或段选择器)。EDX:通用寄存器。在某些运算中作为EAX的溢出寄存器(例如乘、除)。在保护模式中,也可以作为内存偏移指针(此时,DS作为段寄存器或选择器)。同AX分为AH&AL一样,上述寄存器包括对应的16-bit分组和8-bit分组。B、用作内存指针的特殊寄存器ESI:通常在内存操作指令中作为“源地址指针”使用。当然,ESI可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。DS是默认段寄存器或选择器。EDI:通常在内存操作指令中作为“目的地

13、址指针”使用。当然,EDI也可以被装入任意的数值,但通常没有人把它当作通用寄存器来用。DS是默认段寄存器或选择器。EBP:这也是一个作为指针的寄存器。通常,它被高级语言编译器用以建造堆栈帧来保存函数或过程的局部变量,不过,还是那句话,你可以在其中保存你希望的任何数据。SS是它的默认段寄存器或选择器。注意,这三个寄存器没有对应的8-bit分组。换言之,你可以通过SI、DI、BP作为别名访问他们的低16位,却没有办法直接访问他们的低8位。C、段选择器:实模式下的段寄存器到保护模式下摇身一变就成了选择器。不同的是,实模式下的“段寄存器”是16-bit的,而保护模式下的选择器是32-bit的。CS代码

14、段,或代码选择器。同IP寄存器(稍后介绍)一同指向当前正在执行的那个地址。处理器执行时从这个寄存器指向的段(实模式)或内存(保护模式)中获取指令。除了跳转或其他分支指令之外,你无法修改这个寄存器的内容。DS数据段,或数据选择器。这个寄存器的低16bit连同ESI一同指向的指令将要处理的内存。同时,所有的内存操作指令默认情况下都用它指定操作段(实模式)或内存(作为选择器,在保护模式。这个寄存器可以被装入任意数值,然而在这么做的时候需要小心一些。方法是,首先把数据送给AX,然后再把它从AX传送给DS(当然,也可以通过堆栈来做).ES附加段,或附加选择器。这个寄存器的低16bit连同EDI一同指向的

15、指令将要处理的内存。同样的,这个寄存器可以被装入任意数值,方法和DS类似。FSF段或F选择器(推测F可能是Free?)。可以用这个寄存器作为默认段寄存器或选择器的一个替代品。它可以被装入任何数值,方法和DS类似。GSG段或G选择器(G的意义和F一样,没有在Intel的文档中解释)。它和FS几乎完全一样。SS堆栈段或堆栈选择器。这个寄存器的低16bit连同ESP一同指向下一次堆栈操作(push和pop)所要使用的堆栈地址。这个寄存器也可以被装入任意数值,你可以通过入栈和出栈操作来给他赋值,不过由于堆栈对于很多操作有很重要的意义,因此,不正确的修改有可能造成对堆栈的破坏。*注意一定不要在初学汇编的

16、阶段把这些寄存器弄混。他们非常重要,而一旦你掌握了他们,你就可以对他们做任意的操作了。段寄存器,或选择器,在没有指定的情况下都是使用默认的那个。这句话在现在看来可能有点稀里糊涂,不过你很快就会在后面知道如何去做。指令指针寄存器:EIP这个寄存器非常的重要。这是一个32位宽的寄存器,同CS一同指向即将执行的那条指令的地址。不能够直接修改这个寄存器的值,修改它的唯一方法是跳转或分支指令。(CS是默认的段或选择器)上面是最基本的寄存器。下面是一些其他的寄存器,你甚至可能没有听说过它们。(都是32位宽):CR0,CR2,CR3(控制寄存器)。举一个例子,CR0的作用是切换实模式和保护模式。还有其他一些

17、寄存器,D0,D1,D2,D3,D6和D7(调试寄存器)。他们可以作为调试器的硬件支持来设置条件断点。TR3,TR4,TR5,TR6和TR?寄存器(测试寄存器)用于某些条件测试。HYPERLINK/view/6159.htmll#编辑本段寄存器分类数据寄存器-用来储存整数数字(参考以下的浮点寄存器)。在某些简单/旧的CPU,特别的数据寄存器是累加器,作为数学计算之用。地址寄存器-持有存储器地址,以及用来访问存储器。在某些简单/旧的CPU里,特别的地址寄存器是索引寄存器(可能出现一个或多个)。通用目的寄存器(GPRs)-可以保存数据或地址两者,也就是说他们是结合数据/地址寄存器的功用。浮点寄存器

18、(FPRs)-用来储存浮点数字。常数寄存器-用来持有只读的数值(例如0、1、圆周率等等)。向量寄存器-用来储存由向量处理器运行SIMD(SingleInstruction,MultipleData)指令所得到的数据。特殊目的寄存器-储存CPU内部的数据,像是程序计数器(或称为指令指针),堆栈寄存器,以及状态寄存器(或称微处理器状态字组)。指令寄存器(instructionregister)-储存现在正在被运行的指令索引寄存器(indexregister)-是在程序运行实用来更改运算对象地址之用。在某些架构下,模式指示寄存器(也称为“机器指示寄存器”)储存和设置跟处理器自己有关的数据。由于他们的

19、意图目的是附加到特定处理器的设计,因此他们并不被预期会成微处理器世代之间保留的标准。有关从随机存取存储器提取信息的寄存器与CPU(位于不同芯片的储存寄存器集合)存储器缓冲寄存器(Memorybufferregister)存储器数据寄存器(Memorydataregister)存储器地址寄存器(Memoryaddressregister)存储器型态范围寄存器(MemoryTypeRangeRegisters)12实模式1:实模式:寻址采用和8086相同的16位段和偏移量,最大寻址空间1MB,最大分段64KB。可以使用32位指令。32位的x86CPU用做高速的8086。2:保护模式:寻址采用32位

20、段和偏移量,最大寻址空间4GB,最大分段4GB(PentiumPre及以后为64GB)。在保护模式下CPU可以进入虚拟8086方式,这是在保护模式下的实模式程序运行环境。第一:实模式下程序的运行回顾.程序运行的实质是什么?其实很简单,就是指令的执行,显然CPU是指令得以执行的硬件保障,那么CPU如何知道指令在什么地方呢?对了,80 x86系列是使用CS寄存器配合IP寄存器来通知CPU指令在内存中的位置.程序指令在执行过程中一般还需要有各种数据,80 x86系列有DS、ES、FS、GS、SS等用于指示不同用途的数据段在内存中的位置。程序可能需要调用系统的服务子程序,80 x86系列使用中断机制来

21、实现系统服务。总的来说,这些就是实模式下一个程序运行所需的主要内容(其它如跳转、返回、端口操作等相对来说比较次要。)第二:保护模式从程序运行说起无论实模式还是保护模式,根本的问题还是程序如何在其中运行。因此我们在学习保护模式时应该时刻围绕这个问题来思考。和实模式下一样,保护模式下程序运行的实质仍是“CPU执行指令,操作相关数据”,因此实模式下的各种代码段、数据段、堆栈段、中断服务程序仍然存在,且功能、作用不变。那么保护模式下最大的变化是什么呢?答案可能因人而异,我的答案是“地址转换方式”变化最大。第三:地址转换方式比较先看一下实模式下的地址转换方式,假设我们在ES中存入0 x1000,DI中存

22、入0 xFFFF,那么ES:DI=0 x1000*0 x10+0 xFFFF=0 x1FFFF,这就是众所周知的“左移4位加偏移”。那么如果在保护模式下呢?假设上面的数据不变ES=0 x1000,DI=0 xFFFF,现在ES:DI等于什么呢?公式如下:(注:0 x1000=1000000000000b=1000000000000)ES:DI=全局描述符表中第0 x200项描述符给出的段基址+0 xFFFF现在比较一下,好象是不一样。再仔细看看,又好象没什么区别!为什么说没什么区别,因为我的想法是,既然ES中的内容都不是真正的段地址,凭什么实模式下称ES为“段寄存器”,而到了保护模式就说是“选

23、择子”?其实它们都是一种映射,只是映射规则不同而已:在实模式下这个“地址转换方式”是“左移4位”;在保护模式下是“查全局/局部描述表”。前者是系统定义的映射方式,后者是用户自定义的转换方式。而它影响的都是“shadowregister”从函数的观点来看,前者是表达式函数,后者是列举式函数:实模式:F(es-segment)=segment|segment=es*0 x10保护模式:F(es-segment)=segment|(es,segment)GDT/LDT其中GDT、LDT分别表示全局描述符表和局部描述符表。第四:保护模式基本组成保护模式最基本的组成部分是围绕着“地址转换方式”的变化增设

24、了相应的机构。1、数据段前面说过,实模式下的各种代码段、数据段、堆栈段、中断服务程序仍然存在,我将它们统称为“数据段”,本文从此向下凡提到数据段都是使用这个定义。2、描述符保护模式下引入描述符来描述各种数据段,所有的描述符均为8个字节(0-7),由第5个字节说明描述符的类型,类型不同,描述符的结构也有所不同。若干个描述符集中在一起组成描述符表,而描述符表本身也是一种数据段,也使用描述符进行描述。所以CPU中有一个IDr索引寄存器。从现在起,“地址转换”由描述符表来完成,从这个意义上说,描述符表是一张地址转换函数表。3、选择子选择子是一个2字节的数,共16位,最低2位表示RPL,第3位表示查表是

25、利用GDT(全局描述符表)还是LDT(局部描述符表)进行,最高13位给出了所需的描述符在描述符表中的地址。(注:13位正好足够寻址8K项)有了以上三个概念之后可以进一步工作了,现在程序的运行与实模式下完全一样!各段寄存器仍然给出一个“段值”,只是这个“假段值”到真正的段地址的转换不再是“左移4位”,而是利用描述符表来完成。但现在出现一个新的问题是:系统如何知道GDT/LDT在内存中的位置呢?为了解决这个问题,显然需要引入新的寄存器用于指示GDT/LDT在内存中的位置。在80 x86系列中引入了两个新寄存器GDR和LDR,其中GDR用于表示GDT在内存中的段地址和段限(就是表的大小),因此GDR

26、是一个48位的寄存器,其中32位表示段地址,16位表示段限(最大64K,每个描述符8字节,故最多有64K/8=8K个描述符)。LDR用于表示LDT在内存中的位置,但是因为LDT本身也是一种数据段,它必须有一个描述符,且该描述符必须放在GDT中,因此LDR使用了与DS、ES、CS等相同的机制,其中只存放一个“选择子”,通过查GDT表获得LDT的真正内存地址。对了,还有中断要考虑,在80 x86系列中为中断服务提供中断/陷阱描述符,这些描述符构成中断描述符表(IDT),并引入一个48位的全地址寄存器存放IDT的内存地址。理论上IDT表同样可以有8K项,可是因为80 x86只支持256个中断,因此I

27、DT实际上最大只能有256项(2K大小)。第五:新要求任务篇前面介绍了保护模式的基本问题,也是核心问题,解决了上面的问题,程序就可以在保护模式下运行了。但众所周知80286以后在保护模式下实现了对多任务的硬件支持。我的第一反应是:为什么不在实模式下支持多任务,是不能还是不愿?思考之后,我的答案是:实模式下能实现多任务(也许我错了:)。因为多任务的关键是有了描述符,可以给出关于数据段的额外描述,如权限等,进而在这些附加信息的基础上进行相应的控制,而实模式下缺乏描述符,但假设我们规定各段的前2个字节或若干字节用于描述段的附加属性,我觉得和使用描述符这样的机制没有本质区别,如果再附加其他机制.基于上

28、述考虑,我更倾向于认为任务是独立于保护模式之外的功能。下面我们来分析一下任务。任务的实质是什么呢?很简单,就是程序嘛!所谓任务的切换其实就是程序的切换!现在问题明朗了。实模式下程序一个接一个运行,因此程序运行的“环境”不必保存;保护模式下可能一个程序在运行过程中被暂停,转而执行下一个程序,我们要做什么?很容易想到保存程序运行的环境就行了(想想游戏程序的保存进度功能),比如各寄存器的值等。显然这些“环境”数据构成了一类新的数据段(即TSS)。延用前面的思路,给这类数据段设置描述符(TSS描述符),将该类描述符放在GDT中(不能放在LDT中,因为80 x86不允许:),最后再加一个TR寄存器用于查

29、表。TR是一个起“选择子”作用的寄存器,16位。好了,任务切换的基本工作就是将原任务的“环境”存入TSS数据段,更新TR寄存器,系统将自动查GDT表获得并装载新任务的“环境”,然后转到新任务执行。第六:附加要求分页篇为什么叫附加要求,因为现在任务还不能很好地工作。前面说过,任务实质上是程序,不同的程序是由不同的用户写的,所有这些程序完全可能使用相同的地址空间,而任务的切换过程一般不会包括内存数据的刷新,不是不可能,而是如果那样做太浪费了。因此必须引入分页机制才可能有效地完成对多任务的支持。分页引入的主要目标就是解决不同任务相互之间发生地址冲突的问题。分页的实质就是实现程序内地址到物理地址的映射

30、,这也是一个“地址转换”机制,同样可以使用前面的方案(即类似GDT的做法):首先建立页表这样一种数据段,在80 x86中使用二级页表方案,增设一个CR3寄存器用于存放一级页表(又称为页目录)在内存中的地址,CR3共32位,其低12位总是为零,高20位指示页目录的内存地址,因此页目录总是按页对齐的。CR3作为任务“环境”的一部分在任务切换时被存入TSS数据段中。当然还得有相应的缺页中断机制及其相关寄存器CR2(页故障线性地址寄存器)。第七:总结保护模式下增加了什么?1、寄存器GDRLDRIDRTRCR32、数据段描述符表(GDTLDT)任务数据段(TSS)页表(页目录二级页表)3、机制权限检测(

31、利用选择子/描述符/页表项的属性位)线性地址到物理地址的映射第八:保护模式常用名词解释前面内容中出现过的不再解释。1、RPL选择子当中的权限位确定的权限2、CPL特指CS中的选择子当中的权限位确定的权限3、EPLEPL=Max(RPL,CPL),即RPL和CPL中数值较大的,或说权限等级较小的4、DPL描述符中的权限位确定的权限5、PL泛指以上4种特权级6、任务特权=CPL7、I/O特权由EFLAGS寄存器的位13、14确定的权限8、一致代码段一种特殊的代码段,它在CPL=DPL时允许访问正常的代码段在CPL=DPLRPL=DPL时才允许访问MMUMMU是MemoryManagementUni

32、t的缩写,中文名是内存管理单元,它是中央处理器(CPU)中用来管理虚拟存储器、物理存储器的控制线路,同时也负责虚拟地址映射为物理地址,以及提供硬件机制的内存访问授权。一、MMU的历史许多年以前,当人们还在使用DOS或是更古老的操作系统的时候,计算机的内存还非常小,一般都是以K为单位进行计算,相应的,当时的程序规模也不大,所以内存容量虽然小,但还是可以容纳当时的程序。但随着图形界面的兴起还有用户需求的不断增大,应用程序的规模也随之膨胀起来,终于一个难题出现在程序员的面前,那就是应用程序太大以至于内存容纳不下该程序,通常解决的办法是把程序分割成许多称为覆盖块(overlay)的片段。覆盖块0首先运

33、行,结束时他将调用另一个覆盖块。虽然覆盖块的交换是由OS完成的,但是必须先由程序员把程序先进行分割,这是一个费时费力的工作,而且相当枯燥。人们必须找到更好的办法从根本上解决这个问题。不久人们找到了一个办法,这就是虚拟存储器(virtualmemory).虚拟存储器的基本思想是程序,数据,堆栈的总的大小可以超过物理存储器的大小,操作系统把当前使用的部分保留在内存中,而把其他未被使用的部分保存在磁盘上。比如对一个16MB的程序和一个内存只有4MB的机器,操作系统通过选择,可以决定各个时刻将哪4M的内容保留在内存中,并在需要时在内存和磁盘间交换程序片段,这样就可以把这个16M的程序运行在一个只具有4

34、M内存机器上了。而这个16M的程序在运行前不必由程序员进行分割。二、MMU的相关概念地址范围、虚拟地址映射为物理地址以及分页机制任何时候,计算机上都存在一个程序能够产生的地址集合,我们称之为地址范围。这个范围的大小由CPU的位数决定,例如一个32位的CPU,它的地址范围是00 xFFFFFFFF(4G),而对于一个64位的CPU,它的地址范围为00 xFFFFFFFFFFFFFFFF(64T).这个范围就是我们的程序能够产生的地址范围,我们把这个地址范围称为虚拟地址空间,该空间中的某一个地址我们称之为虚拟地址。与虚拟地址空间和虚拟地址相对应的则是物理地址空间和物理地址,大多数时候我们的系统所具

35、备的物理地址空间只是虚拟地址空间的一个子集。这里举一个最简单的例子直观地说明这两者,对于一台内存为256M的32bitx86主机来说,它的虚拟地址空间范围是00 xFFFFFFFF(4G),而物理地址空间范围是0 x0000000000 x0FFFFFFF(256M)。在没有使用虚拟存储器的机器上,虚拟地址被直接送到内存总线上,使具有相同地址的物理存储器被读写;而在使用了虚拟存储器的情况下,虚拟地址不是被直接送到内存地址总线上,而是送到存储器管理单元MMU,把虚拟地址映射为物理地址。大多数使用虚拟存储器的系统都使用一种称为分页(paging)机制。虚拟地址空间划分成称为页(page)的单位,而

36、相应的物理地址空间也被进行划分,单位是页桢(frame).页和页桢的大小必须相同。在这个例子中我们有一台可以生成32位地址的机器,它的虚拟地址范围从00 xFFFFFFFF(4G),而这台机器只有256M的物理地址,因此他可以运行4G的程序,但该程序不能一次性调入内存运行。这台机器必须有一个达到可以存放4G程序的外部存储器(例如磁盘或是FLASH),以保证程序片段在需要时可以被调用。在这个例子中,页的大小为4K,页桢大小与页相同这点是必须保证的,因为内存和外围存储器之间的传输总是以页为单位的。对应4G的虚拟地址和256M的物理存储器,他们分别包含了1M个页和64K个页桢。三、MMU的功能1、将

37、虚拟地址映射为物理地址现代的多用户多进程操作系统,需要MMU,才能达到每个用户进程都拥有自己独立的地址空间的目标。使用MMU,操作系统划分出一段地址区域,在这块地址区域中,每个进程看到的内容都不一定一样。例如MICROSOFTWINDOWS操作系统将地址范围4M-2G划分为用户地址空间,进程A在地址0X400000(4M)映射了可执行文件,进程B同样在地址0X400000(4M)映射了可执行文件,如果A进程读地址0X400000,读到的是A的可执行文件映射到RAM的内容,而进程B读取地址0X400000时,则读到的是B的可执行文件映射到RAM的内容。这就是MMU在当中进行地址转换所起的作用。2

38、、提供硬件机制的内存访问授权多年以来,微处理器一直带有片上存储器管理单元(MMU),MMU能使单个软件线程工作于硬件保护地址空间。但是在许多商用实时操作系统中,即使系统中含有这些硬件也没采用MMU。当应用程序的所有线程共享同一存储器空间时,任何一个线程将有意或无意地破坏其它线程的代码、数据或堆栈。异常线程甚至可能破坏内核代码或内部数据结构。例如线程中的指针错误就能轻易使整个系统崩溃,或至少导致系统工作异常。就安全性和可靠性而言,基于进程的实时操作系统(RTOS)的性能更为优越。为生成具有单独地址空间的进程,RTOS只需要生成一些基于RAM的数据结构并使MMU加强对这些数据结构的保护。基本思路是

39、在每个关联转换中“接入”一组新的逻辑地址。MMU利用当前映射,将在指令调用或数据读写过程中使用的逻辑地址映射为存储器物理地址。MMU还标记对非法逻辑地址进行的访问,这些非法逻辑地址并没有映射到任何物理地址。这些进程虽然增加了利用查询表访问存储器所固有的系统开销,但其实现的效益很高。在进程边界处,疏忽或错误操作将不会出现,用户接口线程中的缺陷并不会导致其它更关键线程的代码或数据遭到破坏。目前在可靠性和安全性要求很高的复杂嵌入式系统中,仍然存在采无存储器保护的操作系统的情况,这实在有些不可思议。采用MMU还有利于选择性地将页面映射或解映射到逻辑地址空间。物理存储器页面映射至逻辑空间,以保持当前进程

40、的代码,其余页面则用于数据映射。类似地,物理存储器页面通过映射可保持进程的线程堆栈。RTOS可以在每个线程堆栈解映射之后,很容易地保留逻辑地址所对应的页面内容。这样,如果任何线程分配的堆栈发生溢出,将产生硬件存储器保护故障,内核将挂起该线程,而不使其破坏位于该地址空间中的其它重要存储器区,如另一线程堆栈。这不仅在线程之间,还在同一地址空间之间增加了存储器保护。存储器保护(包括这类堆栈溢出检测)在应用程序开发中通常非常有效。采用了存储器保护,程序错误将产生异常并能被立即检测,它由源代码进行跟踪。如果没有存储器保护,程序错误将导致一些细微的难以跟踪的故障。实际上,由于在扁平存储器模型中,RAM通常

41、位于物理地址的零页面,因此甚至NULL指针引用的解除都无法检测到。四、MMU和CPU1、X86系列的MMUINTEL出品的80386CPU或者更新的CPU中都集成有MMU.可以提供32BIT共4G的地址空间.X86MMU提供的寻址模式有4K/2M/4M的PAGE模式(根据不同的CPU,提供不同的能力),此处提供的是目前大部分操作系统使用的4K分页机制的描述,并且不提供ACCESSCHECK的部分。涉及的寄存器a)GDTb)LDTc)CR0d)CR3e)SEGMENTREGISTER虚拟地址到物理地址的转换步骤a)SEGMENTREGISTER作为GDT或者LDT的INDEX,取出对应的GDT/

42、LDTENTRY.注意:SEGMENT是无法取消的,即使是FLAT模式下也是如此.说FLAT模式下不使用SEGMENTREGISTER是错误的.任意的RAM寻址指令中均有DEFAULT的SEGMENT假定.除非使用SEGMENTOVERRIDEPREFIX来改变当前寻址指令的SEGMENT,否则使用的就是DEFAULTSEGMENT.ENTRY格式typedefstructUINT16limit_0_15;UINT16base_0_15;UINT8base_16_23;UINT8accessed:1;UINT8readable:1;UINT8conforming:1;UINT8code_dat

43、a:1;UINT8app_system:1;UINT8dpl:2;UINT8present:1;UINT8limit_16_19:4;UINT8unused:1;UINT8always_0:1;UINT8seg_16_32:1;UINT8granularity:1;UINT8base_24_31;CODE_SEG_DESCRIPTOR,*PCODE_SEG_DESCRIPTOR;typedefstructUINT16limit_0_15;UINT16base_0_15;UINT8base_16_23;UINT8accessed:1;UINT8writeable:1;UINT8expanddow

44、n:1;UINT8code_data:1;UINT8app_system:1;UINT8dpl:2;UINT8present:1;UINT8limit_16_19:4;UINT8unused:1;UINT8always_0:1;UINT8seg_16_32:1;UINT8granularity:1;UINT8base_24_31;DATA_SEG_DESCRIPTOR,*PDATA_SEG_DESCRIPTOR;共有4种ENTRY格式,此处提供的是CODESEGMENT和DATASEGMENT的ENTRY格式.FLAT模式下的ENTRY在base_0_15,base_16_23处为0,而lim

45、it_0_15,limit_16_19处为0 xfffff.granularity处为1.表名SEGMENT地址空间是从0到0XFFFFFFFF的4G的地址空间.b)从SEGMENT处取出BASEADDRESS和LIMIT.将要访问的ADDRESS首先进行ACCESSCHECK,是否超出SEGMENT的限制.c)将要访问的ADDRESS+BASEADDRESS,形成需要32BIT访问的虚拟地址.该地址被解释成如下格式:typedefstructUINT32offset:12;UINT32page_index:10;UINT32pdbr_index:10;VA,*LPVA;d)pdbr_inde

46、x作为CR3的INDEX,获得到一个如下定义的数据结构typedefstructUINT8present:1;UINT8writable:1;UINT8supervisor:1;UINT8writethrough:1;UINT8cachedisable:1;UINT8accessed:1;UINT8reserved1:1;UINT8pagesize:1;UINT8ignoreed:1;UINT8avl:3;UINT8ptadr_12_15:4;UINT16ptadr_16_31;PDE,*LPPDE;e)从中取出PAGETABLE的地址.并且使用page_index作为INDEX,得到如下数据

47、结构typedefstructUINT8present:1;UINT8writable:1;UINT8supervisor:1;UINT8writethrough:1;UINT8cachedisable:1;UINT8accessed:1;UINT8dirty:1;UINT8pta:1;UINT8global:1;UINT8avl:3;UINT8ptadr_12_15:4;UINT16ptadr_16_31;PTE,*LPPTE;f)从PTE中获得PAGE的真正物理地址的BASEADDRESS.此BASEADDRESS表名了物理地址的.高20位.加上虚拟地址的offset就是物理地址所在了.2

48、、ARM系列的MMUARM出品的CPU,MMU作为一个协处理器存在。根据不同的系列有不同搭配。需要查询DATASHEET才可知道是否有MMU。如果有的话,一定是编号为15的协处理器。可以提供32BIT共4G的地址空间。ARMMMU提供的分页机制有1K/4K/64K3种模式.本文介绍的是目前操作系统通常使用的4K模式。涉及的寄存器,全部位于协处理器15.ARM没有SEGMENT的寄存器,是真正的FLAT模式的CPU。给定一个ADDRESS,该地址可以被理解为如下数据结构:typedefstructUINT32offset:12;UINT32page_index:8;UINT32pdbr_inde

49、x:12;VA,*LPVA;从MMU寄存器2中取出BIT14-31,pdbr_index就是这个表的索引,每个入口为4BYTE大小,结构为typedefstructUINT32type:2;/alwayssetto01bUINT32writebackcacheable:1;UINT32writethroughcacheable:1;UINT32ignore:1;/setto1balwaysUINT32domain:4;UINT32reserved:1;/set0UINT32base_addr:22;PDE,*LPPDE;获得的PDE地址,获得如下结构的ARRAY,用page_index作为索引

50、,取出内容。typedefstructUINT32type:2;/alwayssetto11bUINT32ignore:3;/setto100balwaysUINT32domain:4;UINT32reserved:3;/set0UINT32base_addr:20;PTE,*LPPTE;从PTE中获得的基地址和上offset,组成了物理地址.PDE/PTE中其他的BIT,用于访问控制。这边讲述的是一切正常,物理地址被正常组合出来的状况。ARM/X86MMU使用上的差异1、X86始终是有SEGMENT的概念存在.而ARM则没有此概念(没有SEGMENTREGISTER.).2、ARM有个DOM

51、AIN的概念.用于访问授权.这是X86所没有的概念.当通用OS尝试同时适用于此2者的CPU上,一般会抛弃DOMAIN的使用.CPU寄存器概述来源:作者:fox时间:2009-07-09点击:1591.什么是寄存器所谓寄存器(register),它是CPU内部用来存放数据的一些小型存储区域,用来暂时存放参与运算的数据和运算结果。其实寄存器就是一种常用的时序逻辑电路,但这种时序逻辑电路只包含存储电路。寄存器的存储电路是由锁存器或触发器构成的,因为一个锁存器或触发器能存储1位二进制数,所以由N个锁存器或触发器可以构成N位寄存器。2.寄存器与CPU指令在讲CPU的寄存器之前,我们先了解一下CPU指令系

52、统。指令系统指的是一个CPU所能够处理的全部指令的集合,AthlonXP和P4都是基于x86指令集,这是CPU的根本属性,决定CPU运行什么样的程序。指令一般分为:算术逻辑运算指令、浮点运算指令、位操作指令及其他的一些非运算指令,其中整数、地址、指令指针和浮点数据是按照数据形式来划分的。通常我们把需要CPU进行不同处理的单个数据称为标量数据(ScalaData)。标量数据既可以是整数数据,也可以是浮点数据。其中整数标量数据的存放区一般为通用寄存器(GPR),浮点标量数据的存放区一般为浮点寄存器(FPR)。与标量数据相对的是矢量数据(VectorData),所谓矢量数据就是指一列需要由处理器作相

53、同处理的数据集合。比如处理器在做MP3编码的过程中,需要对内存中的音频文件里的各字节数据作相同的MP3编码操作。那么通常使用MMX或SSE这类单指令多数据流(SIMD)指令,将数个字节打包为一组矢量数据,存放在MMX或SSE寄存器中,再送往相应的功能单元进行统一操作。其中通用寄存器是处理器中最快的存储器,用来保存参加运算的操作数和中间结果。在通用寄存器的设计上,RISC与CISC(也就是我们常说的x86架构)有着很大的不同。CISC的寄存器通常很少只有8个通用寄存器。由于CPU在执行指令过程中,存在指令依赖性,在一定程度上使得x86CPU不能在每个时钟周期中立即发布大量的指令。所谓“依赖性”就

54、是指令的执行需要前个指令的运算结果。比如程序员经常使用的分支程序,请看下面这个例子:A=C*1B=A+2只要变量A的值还不知道,B=A+2就不能进行运算。也就是说,只要指令1的结果没有写进寄存器,CPU调度器就不能把指令2发布到执行单元。由于程序分支会造成具有较长流水线CPU运行停滞的,目前常用的解决方法是采用分支预测。不过,分支预测同样存在一个问题:流水线越长,指令潜伏期也越长,等待前一指令运算结果的时间也越长,同样会造成CPU运行停滞。我们知道,程序指令通常都有各类型的条件分支语句,通过验证条件决定执行路线。但CPU执行单元内是通过一项特殊的预测机制选择一条路线直接执行(这样可以避免验证语

55、句条件而处于等待情况),然后在后面进行验证。如果预测正确则继续往下执行,如果发现以前的预测错误,那么就必须返回原地重新开始,以前的指令就会作废。因此,管线越长,意味着出现分支预测错误的机会就越多,越多在管线内的指令会被清除掉,而且重新让管道填满指令的时间也会越长。对于普通处理器来说,如果出现分支预测错误,CPU就不得不将整条流水线清空后从错误的地方重新装满数据、重新执行。毫无疑问这将花更多的时间,整体性能就会下降。因此,针对通用寄存器少的问题,在x86架构中比较完美的解决方法就是增加寄存器的数量和采用“乱序执行”。3.为什么寄存器不够用在上面我们已经提到,寄存器只是用来暂时存放指令值的,如果C

56、PU需要把两个值加起来,它需要用1个寄存器来存放运算结果,用2个寄存器来存放相加的数值。例如,在以下的方程式中:A=2+4*在寄存器1储存“2”;*在寄存器2储存“4”;*在寄存器3储存“寄存器1+寄存器2”;因为在微处理器里面有超过3个寄存器,因此这个运算能够轻易地执行,不会造成用光寄存器的情况。在这些运算被执行之后,所有的3个数值都能够被保留并重新使用,因此如果我们再想在结果加上2的话,处理器只需要执行:寄存器1+寄存器3就可以了。如果微处理器仅有2个剩余的寄存器,而我们又需要再次使用2和4的值,那么这些值在覆盖结果A之前,必须储存在主内存之中。运算执行的过程则会变成如下所示:*在寄存器1

57、储存“2”;*在寄存器2储存“4”;*在主内存的某个空间储存“寄存器1+寄存器2”;我们可以看到这里使用了其它的内存访问过程,而在这期间其实还有我们没有提到的其它处理过程,比如主内存的定位也需要占据寄存器,以便让CPU告诉装载/储存单元该往哪里发送数据。如果我们需要使用到这些结果的话,那么CPU将不得不首先到主内存中找回这些结果,把目前满载的寄存器驱逐一些数据,把它们写入主内存,然后再把寻找到的数据储存在寄存器里。这里大家应该能够明白吧,对内存的访问次数将会可怕地增加;你需要访问内存的时间越多,那么处理器等待工作完成的时间就越长因而造成性能的下降。因此面对超标量CPU在并行处理大量运算,x86体系仅有的8个通用寄存器远远不能满足需要,在同一时钟周期中,如果有3个指令发布,你就需要3个输出寄存器和6个输入寄存器。我们该怎么办呢?聪明的工程师们发现了突破这个限制的方法:“寄存器重命名”。4.寄存器重命名技术寄存器重命名,是CPU在解码过程中对寄存器进行重命名,解码器把“其它”的寄存器名字变为“通用”的寄存器名字,本质上是通过一个表格把x86寄存器重新映射到其它寄存器,这样可以让实际使用到的寄存器远大于8个。这样做的好处除了便于前面指令发生意外或分支预测出错时取消外,还避免了由于两条指令写同一个寄存器时的等待。下面我们以一个超标量CPU执行8个算术指令为例:假设

温馨提示

  • 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
  • 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
  • 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
  • 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
  • 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
  • 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
  • 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

评论

0/150

提交评论