首页 > 代码库 > 【译】x86程序员手册18-6.3.1描述符保存保护参数
【译】x86程序员手册18-6.3.1描述符保存保护参数
6.3 Segment-Level Protection 段级保护
All five aspects of protection apply to segment translation:
段转换时会提供以下5个方面的保护:
- Type checking 类型检验
- Limit checking 限长检验
- Restriction of addressable domain 可寻址域的限定
- Restriction of procedure entry points 程序入口点的限定
- Restriction of instruction set 指令集的限定
The segment is the unit of protection, and segment descriptors store protection parameters. Protection checks are performed automatically by the CPU when the selector of a segment descriptor is loaded into a segment register and with every segment access. Segment registers hold the protection parameters of the currently addressable segments.
段是保护的一个单元,段描述符保存了保护参数。当一个段描述符对应的选择子被装入段寄存器以及每个段被访问时,CPU都会自动执行保护检查。段寄存器持有当前可寻址段的保护参数。
6.3.1 Descriptors Store Protection Parameters
描述符保存保护参数
Figure 6-1 highlights the protection-related fields of segment descriptors.
图6-1高亮了段描述符中与保护相关的部分。
The protection parameters are placed in the descriptor by systems software at the time a descriptor is created. In general, applications programmers do not need to be concerned about protection parameters.
系统软件在创建描述符时将保护参数入在描述符中。一般来说,应用程序无需关心保护参数。
When a program loads a selector into a segment register, the processor loads not only the base address of the segment but also protection information. Each segment register has bits in the invisible portion for storing base, limit, type, and privilege level; therefore, subsequent protection checks on the same segment do not consume additional clock cycles.
当程序将一个选择子装入段寄存器中时,处理器不仅把段基址装入,同时也会把保护信息一同装入。每个段寄存器都有一些位是不可见的,它们用来保存基址、限长、类型和特权级别;这样,在同一个段上的保护检查就不需要额外的时钟周期。
6.3.1.1 Type Checking 类型检验
The TYPE field of a descriptor has two functions:
描述符的TYPE段有以下两个功能:
- It distinguishes among different descriptor formats.
区别不同的描述符格式。
- It specifies the intended usage of a segment.
指定段的用法。
Besides the descriptors for data and executable segments commonly used by applications programs, the 80386 has descriptors for special segments used by the operating system and for gates. Table 6-1 lists all the types defined for system segments and gates. Note that not all descriptors define segments; gate descriptors have a different purpose that is discussed later in this chapter.
除了应用程序一般用到的数据段和代码段外,80386还有被操作系统使用的特殊描述符和为门使用的特殊描述符。表6-1列出所有为操作系统和门定义的类型。注意,不是所有的描述符都用来定义段;门描述符有不同的目的,会在本章的后面部分讨论。
The type fields of data and executable segment descriptors include bits which further define the purpose of the segment (refer to Figure 6-1 ):
数据段和代码段的描述符中的类型字段包含以下这些用来定义段目的的位(参见图6-1):
- The writable bit in a data-segment descriptor specifies whether instructions can write into the segment.
数据段描述符中的可写位指定指令可以向这些段写入。
- The readable bit in an executable-segment descriptor specifies whether instructions are allowed to read from the segment (for example, to access constants that are stored with instructions). A readable, executable segment may be read in two ways:
代码段描述符中的可读位指出指令是否可以从该段中读取(例如,访问保存在指令中的静态变量)。一个可读、可执行的段可以使用以下两种方式进行读取:
- Via the CS register, by using a CS override prefix.
通过CS寄存器,使用CS段前缀。
- By loading a selector of the descriptor into a data-segment register (DS, ES, FS,or GS).
把描述符的选择子装入段寄存器(DS、ES、FS或GS)。
Type checking can be used to detect programming errors that would attempt to use segments in ways not intended by the programmer. The processor examines type information on two kinds of occasions:
类型检验可以用来侦测那些试图以程序不希望的方式来使用段的错误。处理器在下面两种情况下检查类型信息:
- When a selector of a descriptor is loaded into a segment register. Certain segment registers can contain only certain descriptor types; for example:
当一个描述符的选择子被装入到段寄存器中时。某一段寄存器只能装入某类描述符;例如:
- The CS register can be loaded only with a selector of an executable segment.
CS寄存器只能装入一个可执行段的选择子。
- Selectors of executable segments that are not readable cannot be loaded into data-segment registers.
不可读的可执行段的选择子不能被装入数据段寄存器。
- Only selectors of writable data segments can be loaded into SS.
只有可写的数据段的选择子能被装入SS寄存器。
- When an instruction refers (implicitly or explicitly) to a segment register. Certain segments can be used by instructions only in certain predefined ways; for example: 当指令引用(隐含或明确的)一个段寄存器时。某些寄存器只能以某种预定义的方式被指令使用;如:
- No instruction may write into an executable segment.
没有指令可以对执行段进行写操作。
- No instruction may write into a data segment if the writable bit is not set.
没有指令可以对一个可写位没有被设置的数据段进行写操作。
- No instruction may read an executable segment unless the readable bit is set.
没有指令能对可执行段进行读操作,除非读位被设置。
Table 6-1. System and Gate Descriptor Types 系统和门描述符类型
Code Type of Segment or Gate
0 -reserved
1 Available 286 TSS
2 LDT
3 Busy 286 TSS
4 Call Gate
5 Task Gate
6 286 Interrupt Gate
7 286 Trap Gate
8 -reserved
9 Available 386 TSS
A -reserved
B Busy 386 TSS
C 386 Call Gate
D -reserved
E 386 Interrupt Gate
F 386 Trap Gate
6.3.1.2 Limit Checking 限长检验
The limit field of a segment descriptor is used by the processor to prevent programs from addressing outside the segment. The processor‘s interpretation of the limit depends on the setting of the G (granularity) bit. For data segments, the processor‘s interpretation of the limit depends also on the E-bit (expansion-direction bit) and the B-bit (big bit) (refer to Table 6-2).
段描述符的限长段被处理器用来阻止程序寻址超出段范围。处理器对限长的解释依赖于粒度位(G)。对于数据段,处理器对限长的解释也依赖于扩展方向位(E)和big 位(B)(参见表6-2)。
When G=0, the actual limit is the value of the 20-bit limit field as it appears in the descriptor. In this case, the limit may range from 0 to 0FFFFFH (2^(20) - 1 or 1 megabyte). When G=1, the processor appends 12 low-order one-bits to the value in the limit field. In this case the actual limit may range from 0FFFH (2^(12) - 1 or 4 kilobytes) to 0FFFFFFFFH(2^(32) - 1 or 4 gigabytes).
当G等于0时,实际限长是描述符中20位限长字段的值。在这种情况下,限长从0到0FFFFFH(2^20 - 1 或1M)。当G等于1时,处理器用1将限长字段值的低12位扩展。在这种情况下,限长是0FFFH(2^12 -1 或4K)到0FFFFFFFFH(2^32 - 1 或4G)。
For all types of segments except expand-down data segments, the value of the limit is one less than the size (expressed in bytes) of the segment. The processor causes a general-protection exception in any of these cases:
除了向下扩展的数据段外,其他所有段类型,其限长值是段大小(用字节表示)减1。在下列情况下处理器会触发普通保护性异常:
- Attempt to access a memory byte at an address > limit.
企图访问大于限长的地址的内存字节。
- Attempt to access a memory word at an address >= limit.
企图访问大于等于限长地址的内存字。
- Attempt to access a memory doubleword at an address >= (limit-2).
企图访问大于等于限长减2的地址的内存双字。
For expand-down data segments, the limit has the same function but is interpreted differently. In these cases the range of valid addresses is from limit + 1 to either 64K or 2^(32) - 1 (4 Gbytes) depending on the B-bit. An expand-down segment has maximum size when the limit is zero. (Turning on the expand-down bit swaps which bytes are accessible and which are not.)
对于向下扩展的数据段,限长具有相同功能,但解释方式不同。在这种情况下,有效地址的范围是从限长加1到64K还是4G(2^32 -1),依赖于B位设置。当限长是0时,向下扩展段有最大的范围。(打开向下扩展位可以切换哪些字节可以访问,哪些不能。)
The expand-down feature makes it possible to expand the size of a stack by copying it to a larger segment without needing also to update intrastack pointers.
向下扩展特性使通过把栈拷贝到一个更大的段中,而不需要更新内部栈指针成为可能。
The limit field of descriptors for descriptor tables is used by the processor to prevent programs from selecting a table entry outside the descriptor table. The limit of a descriptor table identifies the last valid byte of the last descriptor in the table. Since each descriptor is eight bytes long, the limit value is N * 8 - 1 for a table that can contain up to N descriptors.
描述符表的描述符的限长可以被处理器用来阻止程序选择一个描述符表外的表入口。描述符表的限长标识表中最后一个描述符的最大有效字节。既然每个描述符都是8个字节长,限长值就是N*8 - 1,对于一个表来说最多可以包含N个描述符。
Limit checking catches programming errors such as runaway subscripts and invalid pointer calculations. Such errors are detected when they occur, so that identification of the cause is easier. Without limit checking, such errors could corrupt other modules; the existence of such errors would not be discovered until later, when the corrupted module behaves incorrectly, and when identification of the cause is difficult.
限长检验可以捕捉例如下标越界和无效指针计算等的程序错误。这样的错误当发生时被侦测到,因此对于错误源的标识就更容易。没有限长检验,这些错误就会破坏其他模块;这些错误的存在可能直到后来才被发现,比如当被破坏的模块行为不正确时,这样标识错误源就变得困难了。
Table 6-2. Useful Combinations of E, G, and B Bits
E、G和B位的组合用法
Case: 1 2 3 4
Expansion Direction U U D D
G-bit 0 1 0 1
B-bit X X 0 1
Lower bound is: 0 0 LIMIT+1 shl(LIMIT,12,1)+1
Upper bound is: LIMIT shl(LIMIT,12,1) 64K-1 4G-1
Max seg size is: 64K 4G 64K-1 4G-4K
0-FFFF 0-FFFFFFFF !(0-0) !(0-FFF)
Min seg size is: 1 4K 0 0
0-0 0-FFF !(0-FFFF) !(0-FFFFFFFF)
shl (X, 12, 1) = shift X left by 12 bits inserting one-bits on the right
6.3.1.3 Privilege Levels 特权级别
The concept of privilege is implemented by assigning a value from zero to three to key objects recognized by the processor. This value is called the privilege level. The value zero represents the greatest privilege, the value three represents the least privilege. The following processor-recognized objects contain privilege levels:
特权概念就是实现一个从0到3的数值来让处理器识别。这些值叫特权级别。0代表最高级特权,3代表最低级特权。处理器识别的对象包含这些特权级别:
- Descriptors contain a field called the descriptor privilege level (DPL).
描述符包含的段叫描述符特权级别(DPL)。
- Selectors contain a field called the requestor‘s privilege level (RPL). The RPL is intended to represent the privilege level of the procedure that originates a selector.
选择子包含的段叫需求特权级别(RPL)。RPL用来代表最初装载这个选择子的程序的特权级别。
- An internal processor register records the current privilege level (CPL). Normally the CPL is equal to the DPL of the segment that the processor is currently executing. CPL changes as control is transferred to segments with differing DPLs.
处理器的寄存器内部记录了当前特权级别(CPL)。通常CPL等于处理器正在执行时使用的段的DPL。当控制权转移到一个具有不同DPL的段时CPL也被修改。
The processor automatically evaluates the right of a procedure to access another segment by comparing the CPL to one or more other privilege levels. The evaluation is performed at the time the selector of a descriptor is loaded into a segment register. The criteria used for evaluating access to data differs from that for evaluating transfers of control to executable segments; therefore, the two types of access are considered separately in the following sections.
处理器通过比较CPL和其他特权级别来自动计算程序访问其他段的权利。当一个选择子被装入段寄存器时计算发生。这个标准在计算数据访问和控制转移时使用;因此,这两种类型的访问在下面被独立对待。
Figure 6-2 shows how these levels of privilege can be interpreted as rings of protection. The center is for the segments containing the most critical software, usually the kernel of the operating system. Outer rings are for the segments of less critical software.
图6-2所示,这些特权级别如何被解释为保护机制使用的权力。中间是包含关键软件的部分,通常是操作系统的核心。外环部分是不太关键的软件部分。
It is not necessary to use all four privilege levels. Existing software that was designed to use only one or two levels of privilege can simply ignore the other levels offered by the 80386. A one-level system should use privilege level zero; a two-level system should use privilege levels zero and three.
使用所有四个特权级别不是必要的。现存的软件一般都使用一个或两个特权级别,这样就简单忽略80386提供的其他级别。一个级别的系统应该使用特权0;两个级别应当使用特权0和3。
【译】x86程序员手册18-6.3.1描述符保存保护参数