我已经阅读到某些x86 CPU在用户模式下无法修改的寄存器(我相信这些寄存器称为“特权寄存器”)。
但是x86 CPU是否可以在用户模式下读取这些寄存器的值,或者甚至不允许读取?
答案 0 :(得分:5)
通常用于计算的所有寄存器都可以在任何模式下读取/写入(GP整数,x87 / MMX,XMM / YMM / ZMM和AVX512 k0-7
掩码寄存器),但是有许多寄存器基本上是模式/控制设置。可以在用户空间中写入某些“特殊”寄存器,例如段寄存器,MPX bnd
寄存器。
以下寄存器不能在用户模式(特权级别> 0)中读取或写入:
WRMSR
/ RDMSR
以外的指令来访问某些寄存器。这样的寄存器可以在用户模式下访问。例如,内核可以允许用户代码使用WRPMC
和RDPMC
指令访问PMC寄存器。CR4.UMIP
= 0,则可以使用CR0
来读取SMSW
。在AMD处理器上,CR4.UMIP
不可用,SMSW
可以无条件地在任何特权级别执行。 EFLAGS
寄存器所允许的修改有些复杂,如英特尔手册第2卷中所述:
在受保护,兼容或64位模式下使用 所有特权级别都大于0,但小于或等于IOPL 除了IOPL字段和RF,IF,VIP,VIF和 VM;这些仍然不受影响。 AC和ID标志只能修改 如果操作数大小属性为32,则中断标志(IF)为 仅在至少以与特权相同的级别执行时才更改 IOPL。如果POPF / POPFD指令执行不充分 特权,不会发生异常,但特权位不会 改变。
在虚拟8086模式(EFLAGS.VM = 1)下运行时 virtual-8086模式扩展(CR4.VME = 0),POPF / POPFD 仅当IOPL = 3时才可以使用指令;否则,一个 发生一般保护异常(#GP)。如果为虚拟8086模式 启用扩展(CR4.VME = 1),可以将POPF(但不能禁用POPFD)设置为 在IOPL <3的虚拟8086模式下执行。
答案 1 :(得分:2)
可用的寄存器在当前Intel x64-x32-Architectures.Software.Developer.Manual的 3.2节和 3.4节中进行了描述。
通常,并非所有寄存器都可以从 User Mode 中读取,甚至更少的寄存器可以从 User Mode 中写入。
例如,可以从 User Mode 完全读取EFLAGS
寄存器,但是可以从读取所有 System标志和IOPL字段 >无法从用户模式写入3.4.3.3节。