Introduction
These instructions manage the processor rather than compute: they set up memory protection and paging, switch between privilege levels, read and write the model-specific registers (MSRs), and save and restore the state of the floating-point and vector units. Most of them came with the 80286 and 80386, which brought protected mode, and the rest one at a time since.
They work on state that ordinary instructions do not reach:
- the descriptor-table registers: GDTR and IDTR (the base and limit of the global descriptor table and the interrupt descriptor table), and LDTR and TR (segment selectors for the local descriptor table and the task-state segment);
- the control registers CR0, CR2, CR3, CR4 and, in 64-bit mode, CR8, which turn on protected mode, paging and the extensions, and the debug registers DR0 to DR7;
- the MSRs, a space of 64-bit registers numbered by a 32-bit address, which hold everything from the system-call entry points (STAR, LSTAR and the SYSENTER MSRs) to the time-stamp counter;
- the extended control register XCR0, which says which state components XSAVE manages.
Most of them run only at privilege level 0 and raise #GP elsewhere; the rows say
where that is not so. The virtualisation, security and cache instructions have pages
of their own: Virtualisation,
Security and
Cache and memory ordering.
cpuid is on the Flags and
miscellaneous page, and int, iret and the far
branches on the Control transfer
page.
The instructions
In the forms, r is a general register, r/m16 a register
or memory operand in ModRM.r/m, and m a memory operand of the size
shown. NP means that no 66, F2 or F3 prefix may be present.
Descriptor tables and segments
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
lgdt | m16&32m16&64 | 0F 01 /2 (memory) | Loads GDTR from memory: a 16-bit limit, then the base (32 bits, or 64 in 64-bit mode). With a 16-bit operand size only 24 bits of the base are used. Size-named forms: lgdtw (16-bit operand size), lgdtd (32-bit). | 80286 (Intel 80286, 1982); lgdtd 80386 (Intel 80386, 1985) |
sgdt | m | 0F 01 /0 (memory) | Stores GDTR in the same format. It runs at any privilege level unless CR4.UMIP is set. Size-named forms: sgdtw, sgdtd. | 80286 (Intel 80286, 1982); sgdtd 80386 (Intel 80386, 1985) |
lidt | m16&32m16&64 | 0F 01 /3 (memory) | Loads IDTR, the interrupt table, in the same format as lgdt. Size-named forms: lidtw, lidtd. | 80286 (Intel 80286, 1982); lidtd 80386 (Intel 80386, 1985) |
sidt | m | 0F 01 /1 (memory) | Stores IDTR. Any privilege level unless CR4.UMIP is set. Size-named forms: sidtw, sidtd. | 80286 (Intel 80286, 1982); sidtd 80386 (Intel 80386, 1985) |
lldt | r/m16 | 0F 00 /2 | Loads LDTR with a selector of an LDT descriptor in the GDT. | 80286 (Intel 80286, 1982) |
sldt | r/m16r32/r64 | 0F 00 /0 | Stores the LDTR selector. Any privilege level unless CR4.UMIP is set. | 80286 (Intel 80286, 1982) |
ltr | r/m16 | 0F 00 /3 | Loads TR with a selector of a task-state segment, and marks the TSS busy. | 80286 (Intel 80286, 1982) |
str | r/m16r32/r64 | 0F 00 /1 | Stores the TR selector. Any privilege level unless CR4.UMIP is set. | 80286 (Intel 80286, 1982) |
lar | r16/r32/r64, r/m16 | 0F 02 /r | Loads the access-rights bytes of the descriptor a selector names, and sets ZF, if the descriptor is visible at the current privilege level; otherwise clears ZF. Any privilege level. | 80286 (Intel 80286, 1982) |
lsl | r16/r32/r64, r/m16 | 0F 03 /r | Loads the segment limit (in bytes) of the descriptor a selector names, with ZF as for lar. Any privilege level. | 80286 (Intel 80286, 1982) |
verr | r/m16 | 0F 00 /4 | Sets ZF if the segment a selector names can be read at the current privilege level. Any privilege level. | 80286 (Intel 80286, 1982) |
verw | r/m16 | 0F 00 /5 | Sets ZF if the segment can be written. On processors with the microarchitectural data-sampling fixes it also clears internal buffers, which is how operating systems use it today. | 80286 (Intel 80286, 1982) |
arpl | r/m16, r16 | 63 /r | Adjusts the requested privilege level of a selector: if the destination’s RPL is lower than the source’s, raises it to match and sets ZF. Not in 64-bit mode, where 63 is movsxd. | 80286 (Intel 80286, 1982) |
lkgs | r/m16 | F2 0F 00 /6 | Loads GS from a selector, but puts the base into IA32_KERNEL_GS_BASE instead of the GS base, so the kernel’s own GS is kept. 64-bit mode only. CPUID leaf 7, sub-leaf 1: EAX bit 18. | LKGS (Intel, with FRED) |
swapgs | – | 0F 01 F8 | Exchanges the GS base with IA32_KERNEL_GS_BASE, so that kernel entry code can reach its per-processor data. 64-bit mode only. | x86-64 (AMD Opteron, 2003) |
rdfsbase | r32/r64 | F3 0F AE /0 (ModRM.mod 11) | Reads the FS base into a register, at any privilege level when CR4.FSGSBASE is set. 64-bit mode only. CPUID leaf 7: EBX bit 0. | FSGSBASE (Intel Ivy Bridge, 2012) |
rdgsbase | r32/r64 | F3 0F AE /1 (ModRM.mod 11) | Reads the GS base. | FSGSBASE (Intel Ivy Bridge, 2012) |
wrfsbase | r32/r64 | F3 0F AE /2 (ModRM.mod 11) | Writes the FS base, which must be a canonical address. | FSGSBASE (Intel Ivy Bridge, 2012) |
wrgsbase | r32/r64 | F3 0F AE /3 (ModRM.mod 11) | Writes the GS base. | FSGSBASE (Intel Ivy Bridge, 2012) |
Control registers, paging and access
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
mov (control and debug registers) | r32/r64, CRnCRn, r32/r64r32/r64, DRnDRn, r32/r64 | 0F 20 /r0F 22 /r0F 21 /r0F 23 /r | Reads or writes a control register or a debug register; ModRM.reg (with REX.R) gives its number. The general register is 64 bits in 64-bit mode and 32 bits elsewhere. The ordinary mov is on the Data transfer page. | 80386 (Intel 80386, 1985) |
clts | – | 0F 06 | Clears CR0.TS, the task-switched flag, after the operating system has restored the floating-point state. | 80286 (Intel 80286, 1982) |
lmsw | r/m16 | 0F 01 /6 | Loads the low four bits of CR0 (PE, MP, EM, TS), the 80286’s machine status word. It can set PE but not clear it. | 80286 (Intel 80286, 1982) |
smsw | r/m16r32/r64 | 0F 01 /4 | Stores the low bits of CR0. Any privilege level unless CR4.UMIP is set. | 80286 (Intel 80286, 1982) |
invlpg | m | 0F 01 /7 (memory) | Invalidates the TLB entries for the page that holds the address. | 80486 (Intel 80486, 1989) |
invpcid | r64, m128r32, m128 | 66 0F 38 82 /rAPX: EVEX map 4, F3 F2 /r | Invalidates TLB entries by process-context identifier (PCID). The register gives the type (0 one address, 1 one PCID, 2 all including global, 3 all except global), the 16-byte descriptor the PCID and the address. CPUID leaf 7: EBX bit 10. | INVPCID (Intel Haswell, 2013) |
invlpgb | rAX, ECX, EDX (implicit) | NP 0F 01 FE | Broadcasts a TLB invalidation to every processor in the system, for a range of pages that rAX, ECX and EDX describe. CPUID leaf 8000_0008h: EBX bit 3. | INVLPGB and TLBSYNC (AMD Zen 3, 2020) |
tlbsync | – | NP 0F 01 FF | Waits until every invlpgb this processor has sent has completed on the others. | INVLPGB and TLBSYNC (AMD Zen 3, 2020) |
stac | – | NP 0F 01 CB | Sets EFLAGS.AC, which with CR4.SMAP lets the kernel reach user pages for a moment. CPUID leaf 7: EBX bit 20. | SMAP (Intel Broadwell, 2014) |
clac | – | NP 0F 01 CA | Clears EFLAGS.AC, so that supervisor-mode access prevention applies again. | SMAP (Intel Broadwell, 2014) |
rdpkru | – | NP 0F 01 EE | Reads the protection-key rights register PKRU into EAX (ECX must be 0; EDX is cleared). Any privilege level. CPUID leaf 7: ECX bit 3. | Protection keys (Intel Skylake-SP, 2017) |
wrpkru | – | NP 0F 01 EF | Writes EAX to PKRU, which sets for each of the 16 protection keys whether user pages with it may be read or written (ECX and EDX must be 0). Any privilege level. | Protection keys (Intel Skylake-SP, 2017) |
MSRs and counters
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
rdmsr | –r64, imm32 | 0F 32VEX.LZ.F2.M7.W0 F6 /0 id | Reads the MSR whose address is in ECX into EDX:EAX. The second form, from MSR-IMM, takes the address as an immediate and reads into a 64-bit register (64-bit mode only). CPUID leaf 1: EDX bit 5. | Pentium (Intel Pentium, 1993); MSR-IMM form Intel Diamond Rapids (announced) |
wrmsr | – | 0F 30 | Writes EDX:EAX to the MSR whose address is in ECX. It is serialising. | Pentium (Intel Pentium, 1993) |
wrmsrns | –imm32, r64 | NP 0F 01 C6VEX.LZ.F3.M7.W0 F6 /0 id | Writes an MSR as wrmsr does, but without serialising, which is faster. The MSR-IMM form takes the address as an immediate and the value from a 64-bit register. CPUID leaf 7, sub-leaf 1: EAX bit 19. | WRMSRNS (Intel, first listed for Sierra Forest and Grand Ridge); MSR-IMM form Intel Diamond Rapids (announced) |
rdmsrlist | – | F2 0F 01 C6 | Reads up to 64 MSRs in one instruction: RSI points to a table of MSR addresses, RDI to the table of values to fill, and each set bit of RCX picks an entry (it is cleared as the entry is done). 64-bit mode only. CPUID leaf 7, sub-leaf 1: EAX bit 27. | MSRLIST (Intel, first listed for Sierra Forest and Grand Ridge) |
wrmsrlist | – | F3 0F 01 C6 | Writes up to 64 MSRs from the same tables. 64-bit mode only. | MSRLIST (Intel, first listed for Sierra Forest and Grand Ridge) |
urdmsr | r64, r64r64, imm32 | F2 0F 38 F8 /r (ModRM.mod 11)VEX.LZ.F2.M7.W0 F8 /0 id | Reads, in user mode, one of the MSRs the operating system allows, its address in the second operand. 64-bit mode only. CPUID leaf 7, sub-leaf 1: EDX bit 15. | User MSR access (Intel, first listed for Clearwater Forest) |
uwrmsr | r64, r64imm32, r64 | F3 0F 38 F8 /r (ModRM.mod 11)VEX.LZ.F3.M7.W0 F8 /0 id | Writes, in user mode, one of the MSRs the operating system allows. 64-bit mode only. | User MSR access (Intel, first listed for Clearwater Forest) |
rdtsc | – | 0F 31 | Reads the time-stamp counter into EDX:EAX. Any privilege level unless CR4.TSD is set. It is not ordered with the instructions around it. CPUID leaf 1: EDX bit 4. | Pentium (Intel Pentium, 1993) |
rdtscp | – | 0F 01 F9 | Reads the time-stamp counter into EDX:EAX after every earlier instruction has run, and IA32_TSC_AUX (usually the processor number) into ECX. CPUID leaf 8000_0001h: EDX bit 27. | RDTSCP (AMD Athlon 64 (K8 revision F), 2006; Intel Nehalem, 2008) |
rdpid | r32r64 (64-bit mode) | F3 0F C7 /7 (ModRM.mod 11) | Reads IA32_TSC_AUX into a register, without the counter. Any privilege level. CPUID leaf 7: ECX bit 22. | RDPID (Intel Goldmont Plus, 2017) |
rdpmc | – | 0F 33 | Reads the performance-monitoring counter that ECX selects into EDX:EAX. At any privilege level when CR4.PCE is set. | Pentium Pro (Intel Pentium Pro, 1995) |
rdpru | – | NP 0F 01 FD | Reads a processor register that ECX selects (0 MPERF, 1 APERF) into EDX:EAX, at any privilege level if the operating system allows it. CPUID leaf 8000_0008h: EBX bit 4. | RDPRU (AMD Zen 2, 2019) |
System calls, events and halting
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
syscall | – | 0F 05 | Fast call to the kernel: saves the return address in RCX and RFLAGS in R11, and loads CS, SS and RIP from STAR and LSTAR (CSTAR for compatibility mode). EFER.SCE must be set. CPUID leaf 8000_0001h: EDX bit 11. | SYSCALL (AMD K6-2, 1998) |
sysret | – | 0F 07 | Returns from syscall to 32-bit code: RIP from RCX and RFLAGS from R11, CS and SS from STAR. 64-bit form, returning to 64-bit code: sysretq (REX.W 0F 07). | SYSCALL (AMD K6-2, 1998) |
sysenter | – | 0F 34 | Intel’s fast call to the kernel: loads CS, ESP and EIP from the three SYSENTER MSRs. It saves nothing; user code passes its return address in registers. CPUID leaf 1: EDX bit 11. | SYSENTER (Intel Pentium II, 1997) |
sysexit | – | 0F 35 | Returns to user mode: EIP from EDX and ESP from ECX. 64-bit form: sysexitq (REX.W 0F 35), returning to 64-bit code. | SYSENTER (Intel Pentium II, 1997) |
eretu | – | F3 0F 01 CA | Returns from a FRED event handler to user mode, from the frame on the stack. FRED (flexible return and event delivery) replaces the IDT and iret for kernel entry and exit. 64-bit mode only; elsewhere these bytes are clac. CPUID leaf 7, sub-leaf 1: EAX bit 17. | FRED (Intel, first listed for Panther Lake and Clearwater Forest) |
erets | – | F2 0F 01 CA | Returns from a FRED event handler to supervisor mode. 64-bit mode only. | FRED (Intel, first listed for Panther Lake and Clearwater Forest) |
hlt | – | F4 | Stops the processor until an interrupt, NMI or reset arrives. | 8086 (Intel 8086, 1978) |
rsm | – | 0F AA | Resumes from system management mode: restores the state saved when the SMI arrived. Valid only in SMM. | RSM (system management mode) (Intel 386SL, 1990) |
Saving processor state
FXSAVE saves the x87, MMX and SSE state in a 512-byte area aligned to 16 bytes.
XSAVE generalises it: the state is split into numbered components (x87, SSE, AVX,
AVX-512, AMX, CET and more), XCR0 says which ones the operating system manages, and
EDX:EAX picks which ones an instruction saves or restores. The area must be aligned
to 64 bytes. Each instruction has a 64-bit form with REX.W, named with
64, which saves the x87 instruction and data pointers as 64-bit
addresses.
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
fxsave | m512byte | NP 0F AE /0 (memory) | Saves the x87, MMX and XMM registers and MXCSR. Any privilege level. 64-bit form: fxsave64 (REX.W). CPUID leaf 1: EDX bit 24. | FXSAVE and FXRSTOR (Intel Pentium II) |
fxrstor | m512byte | NP 0F AE /1 (memory) | Restores what fxsave saved. 64-bit form: fxrstor64. | FXSAVE and FXRSTOR (Intel Pentium II) |
xsave | mem | NP 0F AE /4 (memory) | Saves the components that EDX:EAX and XCR0 both select, in the standard layout. Any privilege level. 64-bit form: xsave64. CPUID leaf 1: ECX bit 26; CR4.OSXSAVE must be set. | XSAVE (Intel Penryn, 2007) |
xrstor | mem | NP 0F AE /5 (memory) | Restores the selected components; those marked in the area’s header as in their initial state are reset instead. 64-bit form: xrstor64. | XSAVE (Intel Penryn, 2007) |
xsaveopt | mem | NP 0F AE /6 (memory) | Like xsave, but may skip components that are in their initial state or have not changed since the last xrstor from the same area. 64-bit form: xsaveopt64. CPUID leaf 0Dh, sub-leaf 1: EAX bit 0. | XSAVEOPT (Intel Sandy Bridge, 2011) |
xsavec | mem | NP 0F C7 /4 (memory) | Saves in the compacted layout, where only the selected components take space, and skips those in their initial state. 64-bit form: xsavec64. CPUID leaf 0Dh, sub-leaf 1: EAX bit 1. | XSAVEC (Intel Skylake, 2015) |
xsaves | mem | NP 0F C7 /5 (memory) | The supervisor form of xsavec: also saves the supervisor components that IA32_XSS selects, such as the CET and processor-trace state. Privilege level 0 only. 64-bit form: xsaves64. CPUID leaf 0Dh, sub-leaf 1: EAX bit 3. | XSAVES (Intel Skylake, 2015) |
xrstors | mem | NP 0F C7 /3 (memory) | Restores from the compacted layout, supervisor components included. Privilege level 0 only. 64-bit form: xrstors64. | XSAVES (Intel Skylake, 2015) |
xgetbv | – | NP 0F 01 D0 | Reads the extended control register that ECX selects (0 for XCR0) into EDX:EAX. Any privilege level, so programs can see which state the operating system saves. | XSAVE (Intel Penryn, 2007) |
xsetbv | – | NP 0F 01 D1 | Writes EDX:EAX to the extended control register that ECX selects. | XSAVE (Intel Penryn, 2007) |
Tracing and profiling
| Instruction | Forms | Encoding | What it does | Set |
|---|---|---|---|---|
ptwrite | r/m32r/m64 | F3 0F AE /4 | Writes the operand into the Intel Processor Trace stream as a packet, so that software can mark its trace. No 16-bit operand-size form. CPUID leaf 14h: EBX bit 4. | PTWRITE (Intel Goldmont Plus, 2017) |
hreset | imm8 | F3 0F 3A F0 C0 ib | Resets the history the processor keeps for its hardware feedback to the operating system (Intel Thread Director); EAX picks which. The immediate is ignored. Privilege level 0 only. CPUID leaf 7, sub-leaf 1: EAX bit 22. | HRESET (Intel Alder Lake, 2021) |
llwpcb | r32/r64 | XOP.L0.map9 12 /0 (ModRM.mod 11) | Turns on AMD’s lightweight profiling: loads the address of an LWP control block, which sets what to count and where the ring buffer of event records is. Any privilege level. CPUID leaf 8000_0001h: ECX bit 15. | LWP (lightweight profiling) (AMD Bulldozer, 2011) |
slwpcb | r32/r64 | XOP.L0.map9 12 /1 (ModRM.mod 11) | Stores the address of the current LWP control block. | LWP (lightweight profiling) (AMD Bulldozer, 2011) |
lwpins | r32/r64, r/m32, imm32 (the first in XOP.vvvv) | XOP.L0.mapA 12 /0 id | Inserts an event record with the three operands into the LWP ring buffer, and reports in CF whether the buffer overflowed. | LWP (lightweight profiling) (AMD Bulldozer, 2011) |
lwpval | r32/r64, r/m32, imm32 (the first in XOP.vvvv) | XOP.L0.mapA 12 /1 id | Counts a programmed value-sample event, and writes a record each time the counter runs out. | LWP (lightweight profiling) (AMD Bulldozer, 2011) |
Notes
- MOV to and from control registers. The disassembler, like
processors, ignores ModRM.mod in 0F 20 to 0F 23 and always takes a register
operand. It shows every register number, also the reserved ones (CR1, CR5 to CR7,
CR9 and up), which raise #UD when run. AMD processors also reach CR8 outside 64-bit
mode with a
lockprefix onmov cr0. - Size-named forms. Outside 64-bit mode the operand size decides
how much of the base
lgdtandlidtload, so the disassembler, as LLVM does, writes the size into the name (lgdtw,lgdtd…). In 64-bit mode the size is always 64 bits and the plain name is used. - Where SYSCALL and SYSENTER run. Intel processors run
syscallandsysretonly in 64-bit mode; AMD processors runsysenterandsysexitonly outside it (in legacy mode). That is why 32-bit programs on 64-bit systems use different entry paths on the two makers’ processors. - Prefixes. 0F 01 C6 to CA and FD to FF hold several instructions
told apart by the prefix, some only in 64-bit mode. Outside 64-bit mode the
disassembler, as LLVM does, leaves out the 64-bit-only ones, so F2 or F3 0F 01 C6
shows as
wrmsrns. The disassembler, as LLVM does, ignores a 66 or F3 prefix onfxsave,fxrstorandxrstor, and a 66 prefix onxsave; with F3, 0F AE /4 isptwrite. - LWP was dropped with AMD’s Zen (2017).
Links
Reference
- Intel 64 and IA-32 Architectures Software Developer’s Manuals – Intel’s manuals; volume 2 describes each instruction, volume 3 the system architecture, volume 1 XSAVE
- Intel Architecture Instruction Set Extensions Programming Reference – Intel’s description of instructions not yet in the main manual, among them MSRLIST, USER_MSR and MSR-IMM
- AMD64 Architecture Programmer’s Manual, Volume 2 – AMD’s system programming manual
- AMD64 Architecture Programmer’s Manual, Volume 3 – AMD’s reference to the general-purpose and system instructions, with LWP, RDPRU and INVLPGB
- x86 and amd64 instruction reference – Félix Cloutier’s web copy of the instruction pages of Intel’s manual