保护模式下,什么是一致性代码和非一致性代码段

保护模式下,什么是一致性代码和非一致性代码段

  • 李健

    3 票

  • 706
评论 ( 1) •  分享 •  链接 •  2012-01-13 
  • 0
    没有什么问题? –  唐仕强  2012-01-13
3个答案
最 新 
  • 马瑜

    3 票

  • 6000
  • 最佳答案

  • CPL是当前进程的权限级别(Current Privilege Level),是当前正在执行的代码所在的段的特权级,存在于cs和ss寄存器的低2位(第0,1位)。CPL表示的是程序或者说任务的当前特权级,它不属于某个段,当前的程序或任务不可能同时表现出2种特权级,那么CS和SS的第0位和第1位应该总是相同的。尝试将RPL异于CPL的数据段选择子装入SS会引起异常。它们总是相同的。
  • CPL就是CS和SS的段选择子的RPL,CPL存放在CS和SS寄存器的RPL字段内,每当一个代码段/堆栈段(特殊的数据段)选择子装入CS/SS寄存器中时,处理器自动地把CPL存放到CS/SS的RPL字段。
  • RPL说明的是进程对段访问的请求权限(Request Privilege Level), 是对于段选择子而言的,每个段选择子有自己的RPL,它说明的是进程对段访问的请求权限,有点像函数参数。而且RPL对每个段来说不是固定的,2次访问同一段时的RPL可以不同。RPL可能会削弱CPL的作用,例如当前CPL=0的进程要访问一个数据段,它把段选择符中的RPL设为3,这样它对该段仍然只有特权为3的访问权限。处理器通过检查RPL和CPL来确认一下请求是否合法。即便提出访问请求的段有足够的特权级,如果RPL不够也是不行的。 (CPL <= DPL) && (RPL <= DPL)

讨论特权级的比较

  1. CPL表示的是程序或者说任务的当前特权级,它不属于某个段,当前的程序或任务不可能同时表现出2种特权级,那么CS和SS的第0位和第1位应该总是相同的。尝试将RPL异于CPL的数据段选择子装入SS会引起异常。另外后面在论述跳转的时候可以看到,它们总是相同的。
  2. DPL表示的是某个段或门的特权级,当程序要访问段A的时候,会将CPL和段A的DPL作比较,以确定程序是否有权限访问段A。
  3. RPL表示选择子是否有权限访问其所指向的段。选择子指向一个段描述符,段描述符指向一个段,段的特权级由段描述符中的DPL决定。当程序需要访问段 A的时候,需要先通过段A的选择子加载段A的段描述符,然后才能访问段A,在这个过程中CPU会先将段A选择子中的RPL和段A描述符中的DPL作比较,确定选择子是否有权限访问其所指向的段,成功后才是CPL和段A的DPL的比较。 RPL、 DPL之间的比较规则与CPL、DPL之间的比较规则一致。举个例子解释前面这句话的意思:比如当前程序要访问一个数据段A,那么CPL不能大于段A的 DPL,否则失败(后面会讲到这一点)。这是CPL和段A的DPL的比较规则,那么同样段A的RPL、DPL也遵循这样的规则,也就是段A的RPL不能大于段A的DPL。 RPL和CPL不会进行比较。
  4. 不管什么情况下,相同特权级之间的访问总是不会错的,所以后面的讨论中通常会忽略相同特权级之间的比较。
  5. 保护模式下代码段中可以存放数据,但数据段中不能存放代码(跳转不过去)。所以代码段既可以获取代码段中的数据(被读的代码段属性需要可读,就算是获取自身段内数据也需要可读),也可以获取数据段中的数据(数据段总是可读的),还可以跳转到其他代码段。而数据段除了被读取,什么都做不了。
  6. 代码段分为一致代码段和非一致代码段,这会对特权级比较产生影响,是否一致由段描述符的第42位决定。数据段和代码不同,它总是非一致的。代码段只在作为被访问一方(或者说目标代码段)时一致性才会对特权级比较产生影响,在作为访问一方时没有区别。是否一致代码段的区别是,在段间跳转过程中,如果目标代码段是一个特权级更高的一致代码段,那么跳转成功,并且CPL不会改变(CS和SS都不会变),于是CPL异于目标代码段的RPL(CPL数值更大,特权级更低);如果目标代码段是一个特权级更高的非一致代码段,那么跳转是会失败的,此时需要使用调用门。另外,如果目标代码段是一个特权级更低的代码段(不论是否一致),那么跳转总是会失败的,除非使用RETF跳转。
  7. 如果当前程序要访问一个数据段A,那么CPL不能大于段A的DPL,否则失败。也就是说当前程序不能访问特权级更高的数据段。CPL可以小于段A的 DPL,也就是说当前程序可以访问特权级更低的数据段。当前程序对调用门和TSS的访问规则与此一致。
  8. 特权级的检查是在选择子被装入段寄存器的时候进行的。先看相对简单一点的数据段A选择子装入DS的情况(装入ES,FS,GS类似,这里以DS为例说明):段A的DPL必须大于RPL,同时还必须大于CPL(第7点),否则产生异常,段A的RPL不和CPL进行比较。 另外,当程序向低特权级跳转时,会检查CPL和DS指向的段的DPL,如果DPL小于CPL,那么DS会被加载空描述符的选择子。
  9. 数据段A选择子装入SS的情况(只有数据段选择子才能装入SS,代码段选择子不能装入SS,不管是否可读):段A的RPL和DPL都必须和CPL相等,否则失败。 来看下为什么会这样。CPU要保证CS和SS中的第0和第1位(CPL)一致,所以段A的RPL必须等于CPL。CPU还要保证当前程序的特权级和当前使用的堆栈段的特权级一致,所以段A的DPL要等于CPL。
  10. 代码段A选择子装入DS的情况(装入ES,FS,GS类似,这里以DS为例说明):如果段A不可读,装入失败。如果段A是可读的非一致代码段,那么 CPL、段A的RPL都必须等于段A的DPL,否则装入就会失败。如果段A是可读的一致代码段,那么CPL、段A的RPL都可以大于段A的DPL,但不能小于段A的DPL。 代码段A用段超越前缀CS读取自身段内数据的时候,虽然没有选择子的装入过程,但CPU会检查段A是否可读,如果不可读会产生异常。
  11. 最后是代码段的段间跳转。段间跳转可以用JMP、CALL、RETF和调用门。从高特权级到低特权级只能用RETF;从低特权级到高特权级非一致代码段,只能用调用门,而且还必须是用CALL指令来使用调用门;从低特权级到高特权级一致代码段JMP、CALL、调用门都可以。

参考自:

评论 ( 0) •  链接 • 2012-01-13
  • puretear

    2 票

  • 151

保护模式下的“一致”与”非一致“,指的是当前特权级CPL和要访问的目标代码段的DPL的关系说的。

对于“non-conforming code segment”来说,当合法访问到目标代码段时,当前特权级CPL会随着跳转被设定成目标代码段的DPL,因此是“非一致的”;

对于"conforming code segment"来说,当合法访问到目标代码段时,CPL不发生改变,因此是“一致的”;

评论 ( 0) •  链接 • 2012-01-30
  • 李健

    3 票

  • 706

一致代码段是内核开辟出来的供应用程序访问的段,但是不允许用户程序写入数据。

  1. CPL(Current Priviliege Level):它代表了当前代码段的特权等级,由CS和SS的第0位和第1位表示。当程序转移到不同的特权等级的代码时处理器将改变CPL。在遇到一致代 码段时,一致代码可以被相同或者更低特权等级(用户程序)的代码访问。当处理器访问一个与CPL特权等级不同的一致代码段时,CPL不会被改变。
  2. DPL(Descriptor Priviliege Level):表示段或者门的特权等级。它存储在段或者门描述符的DPL字段中。当当前代码段试图访问一个段或者门时,DPL将会和CPL以及RPL作比 较,根据段或者门类型的不同,DPL将会被区别对待: 数据段:DPL规定了可以访问此段的最低特权等级。 非一致代码段(不使用调用门的情况下):DPL规定了访问此段的特权级。 调用门:与数据段一致。 一致代码段和通过调用门访问的非一致代码段:DPL规定了访问此段的最高特权等级。 TSS:与数据段一致。
  3. RPL(Requested Priviliege Level):RPL是通过选择子的第0位和第1位来表示的。处理器通过检查RPL和CPL来确认一个访问请求是否合法。即使提出请求的段有足够的特权级,如果RPL不够也是不行的。也就是说,如果RPL的数字比CPL大,那么RPL将会起决定作用,反之亦然。 似乎下面的解释更直观一些: 对于一致代码段:也就是共享的段. <1>.特权级高的程序不允许访问特权级低的数据:核心态不允许调用用户态的数据. <2>.特权级低的程序可以访问到特权级高的数据.但是特权级不会改变:用户态还是用户态. 对于普通代码段.也就是非一致代码段: <0>.只允许同级间访问. <1>.绝对禁止不同级访问:核心态不用用户态.用户态也不使用核心态.

你可能感兴趣的:(保护模式下,什么是一致性代码和非一致性代码段)