I have read that there are some registers that an x86 CPU cannot modify while in user mode (I believe these registers are called \"privileged registers\").
But can an x8
The registers that are available are described in Section 3.2 and Section 3.4 of the current Intel x64-x32-Architectures.Software.Developer.Manual.
Genrally, not all registers can be read from User Mode and even fewer can be written to from User Mode.
For example, the EFLAGS register can be completely read from User Mode, but all of the System Flags and IOPL Field(s) from Section 3.4.3.3 cannot be written to from User Mode.
All the registers you'd normally use for computation can be read/written in any mode (GP integer, x87/MMX, XMM/YMM/ZMM and AVX512 k0-7 mask registers), but there are many registers that are basically mode/control settings. Some "special" registers can be written in user-space, like segment registers, MPX bnd registers.
The following registers cannot be read from or written to in user mode (privilege level > 0):
WRMSR/RDMSR. Such registers may be accessible in user mode. For example, the kernel may allow user code to access the PMC registers using the WRPMC and RDPMC instructions.CR4.UMIP = 0, CR0 can be read using SMSW. On AMD processors, CR4.UMIP is not available and SMSW can be executed at any privilege level unconditionally.The modifications that are allowed to the EFLAGS register are a little complicated as described in the Intel manual Volume 2:
When operating in protected, compatibility, or 64-bit mode with a privilege level greater than 0, but less than or equal to IOPL, all flags can be modified except the IOPL field and RF, IF, VIP, VIF, and VM; these remain unaffected. The AC and ID flags can only be modified if the operand-size attribute is 32. The interrupt flag (IF) is altered only when executing at a level at least as privileged as the IOPL. If a POPF/POPFD instruction is executed with insufficient privilege, an exception does not occur but privileged bits do not change.
When operating in virtual-8086 mode (EFLAGS.VM = 1) without the virtual-8086 mode extensions (CR4.VME = 0), the POPF/POPFD instructions can be used only if IOPL = 3; otherwise, a general-protection exception (#GP) occurs. If the virtual-8086 mode extensions are enabled (CR4.VME = 1), POPF (but not POPFD) can be executed in virtual-8086 mode with IOPL < 3.