为了访问数据段中的操作数,数据段的段选择符必须被加载进数据段寄存器(DS,ES,FS或GS)或堆栈段寄存器(SS)中。可以使用指令MOV、POP、LDS、LES、LFS、lGS和LSS来加载段寄存器。
在把一个段选择符加载进段寄存器之前,处理器会进行特权级检查,它会把当前运行程序或任务的CPL、段选择符的RPL和段描述符的DPL进行比较。只有当段的DPL数值大于或等于CPL和RPL时,处理器才会把选择符加载进段寄存器中。否则就会产生一个一般保护异常,并且不加载段选择符。
访问数据段时的特权级检查:
可知一个程序或任务可寻址的区域随着其CPL改变而变化。当CPL是0时,此时所有特权级是的数据段都可被访问;当CPL是1时,只有在特权级1到3的数据段可被访问;当CPL是3时,只有处于特权级3的数据段可被访问。
另外,有可能会把数据段保存在代码段中。例如,当代码和数据是在ROM中时。因此,有些时候我们会需要访问代码段中的数据。此时我们可以使用以下方法来访问代码段中的数据:
- 把非一致可读代码段的选择符加载进一个数据段寄存器中。
- 把一致可读代码段的选择符加载进一个数据段寄存器中。
- 使用代码段覆盖前缀(CS)来读取一个选择符已经在CS寄存器中的可读代码段。
访问数据段的相同规则也使用与方法1。方法2则总是有效的,因为一致代码段的特权级等同于CPL,而不管代码段的DPL。方法三也总是有效的,因为CS寄存器的选择的代码段的DPL与CPL相同。
当使用堆栈段选择符加载SS寄存器时也会执行特权级检查。这里与堆栈段相关的所有特权级必须与CPL匹配,也即,CPL、堆栈段选择符RPL以及堆栈段描述符的DPL都必须相同。如果RPL或DPL与CPL不同,处理器就会产生一个一般保护异常。