ia32-64/x86/wrussd.wrussq.html
2025-07-08 02:23:29 -03:00

168 lines
5.8 KiB
HTML
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:svg="http://www.w3.org/2000/svg" xmlns:x86="http://www.felixcloutier.com/x86"><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><link rel="stylesheet" type="text/css" href="style.css"></link><title>WRUSSD/WRUSSQ
— Write to User Shadow Stack</title></head><body><header><nav><ul><li><a href='index.html'>Index</a></li><li>December 2023</li></ul></nav></header><h1>WRUSSD/WRUSSQ
— Write to User Shadow Stack</h1>
<table>
<tr>
<th>Opcode/Instruction</th>
<th>Op/En</th>
<th>64/32 bit Mode Support</th>
<th>CPUID Feature Flag</th>
<th>Description</th></tr>
<tr>
<td>66 0F 38 F5 !(11):rrr:bbb WRUSSD m32, r32</td>
<td>MR</td>
<td>V/V</td>
<td>CET_SS</td>
<td>Write 4 bytes to shadow stack.</td></tr>
<tr>
<td>66 REX.W 0F 38 F5 !(11):rrr:bbb WRUSSQ m64, r64</td>
<td>MR</td>
<td>V/N.E.</td>
<td>CET_SS</td>
<td>Write 8 bytes to shadow stack.</td></tr></table>
<h2 id="instruction-operand-encoding">Instruction Operand Encoding<a class="anchor" href="#instruction-operand-encoding">
</a></h2>
<table>
<tr>
<th>Op/En</th>
<th>Operand 1</th>
<th>Operand 2</th>
<th>Operand 3</th>
<th>Operand 4</th></tr>
<tr>
<td>MR</td>
<td>ModRM:r/m (w)</td>
<td>ModRM:reg (r)</td>
<td>N/A</td>
<td>N/A</td></tr></table>
<h2 id="description">Description<a class="anchor" href="#description">
</a></h2>
<p>Writes bytes in register source to a user shadow stack page. The WRUSS instruction can be executed only if CPL = 0, however the processor treats its shadow-stack accesses as user accesses.</p>
<h2 id="operation">Operation<a class="anchor" href="#operation">
</a></h2>
<pre>IF CR4.CET = 0
THEN #UD; FI;
IF CPL &gt; 0
THEN #GP(0); FI;
DEST_LA = Linear_Address(mem operand)
IF (operand size is 64 bit)
THEN
(* Destination not 8B aligned *)
IF DEST_LA[2:0]
THEN GP(0); FI;
Shadow_stack_store 8 bytes of SRC to DEST_LA as user-mode access;
ELSE
(* Destination not 4B aligned *)
IF DEST_LA[1:0]
THEN GP(0); FI;
Shadow_stack_store 4 bytes of SRC[31:0] to DEST_LA as user-mode access;
FI;
</pre>
<h2 id="flags-affected">Flags Affected<a class="anchor" href="#flags-affected">
</a></h2>
<p>None.</p>
<h2 id="c-c++-compiler-intrinsic-equivalent">C/C++ Compiler Intrinsic Equivalent<a class="anchor" href="#c-c++-compiler-intrinsic-equivalent">
</a></h2>
<pre>WRUSSD void _wrussd(__int32, void *);
</pre>
<pre>WRUSSQ void _wrussq(__int64, void *);
</pre>
<h2 class="exceptions" id="protected-mode-exceptions">Protected Mode Exceptions<a class="anchor" href="#protected-mode-exceptions">
</a></h2>
<table>
<tr>
<td rowspan="2">#UD</td>
<td>If the LOCK prefix is used.</td></tr>
<tr>
<td>If CR4.CET = 0.</td></tr>
<tr>
<td rowspan="5">#GP(0)</td>
<td>If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.</td></tr>
<tr>
<td>If destination is located in a non-writeable segment.</td></tr>
<tr>
<td>If the DS, ES, FS, or GS register is used to access memory and it contains a NULL segment selector.</td></tr>
<tr>
<td>If linear address of destination is not 4 byte aligned.</td></tr>
<tr>
<td>If CPL is not 0.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory operand effective address is outside the SS segment limit.</td></tr>
<tr>
<td rowspan="2">#PF(fault-code)</td>
<td>If destination is not a user shadow stack.</td></tr>
<tr>
<td>Other terminal and non-terminal faults.</td></tr></table>
<h2 class="exceptions" id="real-address-mode-exceptions">Real-Address Mode Exceptions<a class="anchor" href="#real-address-mode-exceptions">
</a></h2>
<table>
<tr>
<td>#UD</td>
<td>The WRUSS instruction is not recognized in real-address mode.</td></tr></table>
<h2 class="exceptions" id="virtual-8086-mode-exceptions">Virtual-8086 Mode Exceptions<a class="anchor" href="#virtual-8086-mode-exceptions">
</a></h2>
<table>
<tr>
<td>#UD</td>
<td>The WRUSS instruction is not recognized in virtual-8086 mode.</td></tr></table>
<h2 class="exceptions" id="compatibility-mode-exceptions">Compatibility Mode Exceptions<a class="anchor" href="#compatibility-mode-exceptions">
</a></h2>
<table>
<tr>
<td rowspan="2">#UD</td>
<td>If the LOCK prefix is used.</td></tr>
<tr>
<td>If CR4.CET = 0.</td></tr>
<tr>
<td rowspan="3">#GP(0)</td>
<td>If a memory address is in a non-canonical form.</td></tr>
<tr>
<td>If linear address of destination is not 4 byte aligned.</td></tr>
<tr>
<td>If CPL is not 0.</td></tr>
<tr>
<td>#SS(0)</td>
<td>If a memory address referencing the SS segment is in a non-canonical form.</td></tr>
<tr>
<td rowspan="2">#PF(fault-code)</td>
<td>If destination is not a user shadow stack.</td></tr>
<tr>
<td>Other terminal and non-terminal faults.</td></tr></table>
<h2 class="exceptions" id="64-bit-mode-exceptions">64-Bit Mode Exceptions<a class="anchor" href="#64-bit-mode-exceptions">
</a></h2>
<table>
<tr>
<td rowspan="2">#UD</td>
<td>If the LOCK prefix is used.</td></tr>
<tr>
<td>If CR4.CET = 0.</td></tr>
<tr>
<td rowspan="3">#GP(0)</td>
<td>If a memory address is in a non-canonical form.</td></tr>
<tr>
<td>If linear address of destination is not 4 byte aligned.</td></tr>
<tr>
<td>If CPL is not 0.</td></tr>
<tr>
<td rowspan="2">#PF(fault-code)</td>
<td>If destination is not a user shadow stack.</td></tr>
<tr>
<td>Other terminal and non-terminal faults.</td></tr></table><footer><p>
This UNOFFICIAL, mechanically-separated, non-verified reference is provided for convenience, but it may be
inc<span style="opacity: 0.2">omp</span>lete or b<sub>r</sub>oke<sub>n</sub> in various obvious or non-obvious
ways. Refer to <a href="https://software.intel.com/en-us/download/intel-64-and-ia-32-architectures-sdm-combined-volumes-1-2a-2b-2c-2d-3a-3b-3c-3d-and-4">Intel® 64 and IA-32 Architectures Software Developers Manual</a> for anything serious.
</p></footer></body></html>