|
|
INSTRUCTION SET REFERENCE, M-U
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If the stack address is in a non-canonical form.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If an unaligned memory reference is made while CPL = 3 and alignment checking is enabled.
#UD
If the LOCK prefix is used.
4-528
Vol. 2B
PUSHF/PUSHFD/PUSHFQ—Push EFLAGS Register Onto the Stack
INSTRUCTION SET REFERENCE, M-U
PXOR—Logical Exclusive OR
Opcode/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NP 0F EF /r1
A
V/V
MMX
Bitwise XOR of mm/m64 and mm.
PXOR mm, mm/m64
66 0F EF /r
A
V/V
SSE2
Bitwise XOR of xmm2/m128 and xmm1.
PXOR xmm1, xmm2/m128
VEX.128.66.0F.WIG EF /r
B
V/V
AVX
Bitwise XOR of xmm3/m128 and xmm2.
VPXOR xmm1, xmm2, xmm3/m128
VEX.256.66.0F.WIG EF /r
B
V/V
AVX2
Bitwise XOR of ymm3/m256 and ymm2.
VPXOR ymm1, ymm2, ymm3/m256
EVEX.128.66.0F.W0 EF /r
C
V/V
AVX512VL
Bitwise XOR of packed doubleword integers in
VPXORD xmm1 {k1}{z}, xmm2, xmm3/m128/m32bcst
AVX512F
xmm2 and xmm3/m128 using writemask k1.
EVEX.256.66.0F.W0 EF /r
C
V/V
AVX512VL
Bitwise XOR of packed doubleword integers in
VPXORD ymm1 {k1}{z}, ymm2, ymm3/m256/m32bcst
AVX512F
ymm2 and ymm3/m256 using writemask k1.
EVEX.512.66.0F.W0 EF /r
C
V/V
AVX512F
Bitwise XOR of packed doubleword integers in
VPXORD zmm1 {k1}{z}, zmm2, zmm3/m512/m32bcst
zmm2 and zmm3/m512/m32bcst using
writemask k1.
EVEX.128.66.0F.W1 EF /r
C
V/V
AVX512VL
Bitwise XOR of packed quadword integers in
VPXORQ xmm1 {k1}{z}, xmm2,
AVX512F
xmm2 and xmm3/m128 using writemask k1.
xmm3/m128/m64bcst
EVEX.256.66.0F.W1 EF /r
C
V/V
AVX512VL
Bitwise XOR of packed quadword integers in
VPXORQ ymm1 {k1}{z}, ymm2, ymm3/m256/m64bcst
AVX512F
ymm2 and ymm3/m256 using writemask k1.
EVEX.512.66.0F.W1 EF /r
C
V/V
AVX512F
Bitwise XOR of packed quadword integers in
VPXORQ zmm1 {k1}{z}, zmm2, zmm3/m512/m64bcst
zmm2 and zmm3/m512/m64bcst using
writemask k1.
NOTES:
1. See note in Section 2.5, “Intel® AVX and Intel® SSE Instruction Exception Specification” in the Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 2A and Section 23.25.3, “Exception Conditions of Legacy SIMD Instructions Operating on MMX Reg-
isters” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 3A.
Instruction Operand Encoding
Op/En
Tuple Type
Operand 1
Operand 2
Operand 3
Operand 4
A
N/A
ModRM:reg (r, w)
ModRM:r/m (r)
N/A
N/A
B
N/A
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
C
Full
ModRM:reg (w)
EVEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Performs a bitwise logical exclusive-OR (XOR) operation on the source operand (second operand) and the destina-
tion operand (first operand) and stores the result in the destination operand. Each bit of the result is 1 if the corre-
sponding bits of the two operands are different; each bit is 0 if the corresponding bits of the operands are the
same.
In 64-bit mode and not encoded with VEX/EVEX, using a REX prefix in the form of REX.R permits this instruction to
access additional registers (XMM8-XMM15).
Legacy SSE instructions 64-bit operand: The source operand can be an MMX technology register or a 64-bit
memory location. The destination operand is an MMX technology register.
PXOR—Logical Exclusive OR
Vol. 2B
4-529
INSTRUCTION SET REFERENCE, M-U
128-bit Legacy SSE version: The second source operand is an XMM register or a 128-bit memory location. The first
source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the corresponding YMM desti-
nation register remain unchanged.
VEX.128 encoded version: The second source operand is an XMM register or a 128-bit memory location. The first
source operand and destination operands are XMM registers. Bits (MAXVL-1:128) of the destination YMM register
are zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand is a YMM register
or a 256-bit memory location. The destination operand is a YMM register. The upper bits (MAXVL-1:256) of the
corresponding register destination are zeroed.
EVEX encoded versions: The first source operand is a ZMM/YMM/XMM register. The second source operand can be
a ZMM/YMM/XMM register, a 512/256/128-bit memory location or a 512/256/128-bit vector broadcasted from a
32/64-bit memory location. The destination operand is a ZMM/YMM/XMM register conditionally updated with
writemask k1.
Operation
PXOR (64-bit operand)
DEST := DEST XOR SRC
PXOR (128-bit Legacy SSE version)
DEST := DEST XOR SRC
DEST[MAXVL-1:128] (Unmodified)
VPXOR (VEX.128 encoded version)
DEST := SRC1 XOR SRC2
DEST[MAXVL-1:128] := 0
VPXOR (VEX.256 encoded version)
DEST := SRC1 XOR SRC2
DEST[MAXVL-1:256] := 0
VPXORD (EVEX encoded versions)
(KL, VL) = (4, 128), (8, 256), (16, 512)
FOR j := 0 TO KL-1
i := j * 32
IF k1[j] OR *no writemask* THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN DEST[i+31:i] := SRC1[i+31:i] BITWISE XOR SRC2[31:0]
ELSE DEST[i+31:i] := SRC1[i+31:i] BITWISE XOR SRC2[i+31:i]
FI;
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[31:0] remains unchanged*
ELSE
; zeroing-masking
DEST[31:0] := 0
FI;
FI;
ENDFOR;
DEST[MAXVL-1:VL] := 0
4-530
Vol. 2B
PXOR—Logical Exclusive OR
INSTRUCTION SET REFERENCE, M-U
VPXORQ (EVEX encoded versions)
(KL, VL) = (2, 128), (4, 256), (8, 512)
FOR j := 0 TO KL-1
i := j * 64
IF k1[j] OR *no writemask* THEN
IF (EVEX.b = 1) AND (SRC2 *is memory*)
THEN DEST[i+63:i] := SRC1[i+63:i] BITWISE XOR SRC2[63:0]
ELSE DEST[i+63:i] := SRC1[i+63:i] BITWISE XOR SRC2[i+63:i]
FI;
ELSE
IF *merging-masking*
; merging-masking
THEN *DEST[63:0] remains unchanged*
ELSE
; zeroing-masking
DEST[63:0] := 0
FI;
FI;
ENDFOR;
DEST[MAXVL-1:VL] := 0
Intel C/C++ Compiler Intrinsic Equivalent
VPXORD __m512i _mm512_xor_epi32(__m512i a, __m512i b)
VPXORD __m512i _mm512_mask_xor_epi32(__m512i s, __mmask16 m, __m512i a, __m512i b)
VPXORD __m512i _mm512_maskz_xor_epi32( __mmask16 m, __m512i a, __m512i b)
VPXORD __m256i _mm256_xor_epi32(__m256i a, __m256i b)
VPXORD __m256i _mm256_mask_xor_epi32(__m256i s, __mmask8 m, __m256i a, __m256i b)
VPXORD __m256i _mm256_maskz_xor_epi32( __mmask8 m, __m256i a, __m256i b)
VPXORD __m128i _mm_xor_epi32(__m128i a, __m128i b)
VPXORD __m128i _mm_mask_xor_epi32(__m128i s, __mmask8 m, __m128i a, __m128i b)
VPXORD __m128i _mm_maskz_xor_epi32( __mmask16 m, __m128i a, __m128i b)
VPXORQ __m512i _mm512_xor_epi64( __m512i a, __m512i b);
VPXORQ __m512i _mm512_mask_xor_epi64(__m512i s, __mmask8 m, __m512i a, __m512i b);
VPXORQ __m512i _mm512_maskz_xor_epi64(__mmask8 m, __m512i a, __m512i b);
VPXORQ __m256i _mm256_xor_epi64( __m256i a, __m256i b);
VPXORQ __m256i _mm256_mask_xor_epi64(__m256i s, __mmask8 m, __m256i a, __m256i b);
VPXORQ __m256i _mm256_maskz_xor_epi64(__mmask8 m, __m256i a, __m256i b);
VPXORQ __m128i _mm_xor_epi64( __m128i a, __m128i b);
VPXORQ __m128i _mm_mask_xor_epi64(__m128i s, __mmask8 m, __m128i a, __m128i b);
VPXORQ __m128i _mm_maskz_xor_epi64(__mmask8 m, __m128i a, __m128i b);
PXOR:__m64 _mm_xor_si64 (__m64 m1, __m64 m2)
(V)PXOR:__m128i _mm_xor_si128 ( __m128i a, __m128i b)
VPXOR:__m256i _mm256_xor_si256 ( __m256i a, __m256i b)
Flags Affected
None.
Numeric Exceptions
None.
Other Exceptions
Non-EVEX-encoded instruction, see Table 2-21, “Type 4 Class Exception Conditions”.
EVEX-encoded instruction, see Table 2-49, “Type E4 Class Exception Conditions”.
PXOR—Logical Exclusive OR
Vol. 2B
4-531
INSTRUCTION SET REFERENCE, M-U
RCL/RCR/ROL/ROR—Rotate
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
D0 /2
RCL r/m8, 1
M1
Valid
Valid
Rotate 9 bits (CF, r/m8) left once.
REX + D0 /2
RCL r/m82, 1
M1
Valid
N.E.
Rotate 9 bits (CF, r/m8) left once.
D2 /2
RCL r/m8, CL
MC
Valid
Valid
Rotate 9 bits (CF, r/m8) left CL times.
REX + D2 /2
RCL r/m82, CL
MC
Valid
N.E.
Rotate 9 bits (CF, r/m8) left CL times.
C0 /2 ib
RCL r/m8, imm8
MI
Valid
Valid
Rotate 9 bits (CF, r/m8) left imm8 times.
REX + C0 /2 ib
RCL r/m82, imm8
MI
Valid
N.E.
Rotate 9 bits (CF, r/m8) left imm8 times.
D1 /2
RCL r/m16, 1
M1
Valid
Valid
Rotate 17 bits (CF, r/m16) left once.
D3 /2
RCL r/m16, CL
MC
Valid
Valid
Rotate 17 bits (CF, r/m16) left CL times.
C1 /2 ib
RCL r/m16, imm8
MI
Valid
Valid
Rotate 17 bits (CF, r/m16) left imm8 times.
D1 /2
RCL r/m32, 1
M1
Valid
Valid
Rotate 33 bits (CF, r/m32) left once.
REX.W + D1 /2
RCL r/m64, 1
M1
Valid
N.E.
Rotate 65 bits (CF, r/m64) left once. Uses a 6
bit count.
D3 /2
RCL r/m32, CL
MC
Valid
Valid
Rotate 33 bits (CF, r/m32) left CL times.
REX.W + D3 /2
RCL r/m64, CL
MC
Valid
N.E.
Rotate 65 bits (CF, r/m64) left CL times. Uses a
6 bit count.
C1 /2 ib
RCL r/m32, imm8
MI
Valid
Valid
Rotate 33 bits (CF, r/m32) left imm8 times.
REX.W + C1 /2 ib
RCL r/m64, imm8
MI
Valid
N.E.
Rotate 65 bits (CF, r/m64) left imm8 times.
Uses a 6 bit count.
D0 /3
RCR r/m8, 1
M1
Valid
Valid
Rotate 9 bits (CF, r/m8) right once.
REX + D0 /3
RCR r/m82, 1
M1
Valid
N.E.
Rotate 9 bits (CF, r/m8) right once.
D2 /3
RCR r/m8, CL
MC
Valid
Valid
Rotate 9 bits (CF, r/m8) right CL times.
REX + D2 /3
RCR r/m82, CL
MC
Valid
N.E.
Rotate 9 bits (CF, r/m8) right CL times.
C0 /3 ib
RCR r/m8, imm8
MI
Valid
Valid
Rotate 9 bits (CF, r/m8) right imm8 times.
REX + C0 /3 ib
RCR r/m82, imm8
MI
Valid
N.E.
Rotate 9 bits (CF, r/m8) right imm8 times.
D1 /3
RCR r/m16, 1
M1
Valid
Valid
Rotate 17 bits (CF, r/m16) right once.
D3 /3
RCR r/m16, CL
MC
Valid
Valid
Rotate 17 bits (CF, r/m16) right CL times.
C1 /3 ib
RCR r/m16, imm8
MI
Valid
Valid
Rotate 17 bits (CF, r/m16) right imm8 times.
D1 /3
RCR r/m32, 1
M1
Valid
Valid
Rotate 33 bits (CF, r/m32) right once. Uses a 6
bit count.
REX.W + D1 /3
RCR r/m64, 1
M1
Valid
N.E.
Rotate 65 bits (CF, r/m64) right once. Uses a 6
bit count.
D3 /3
RCR r/m32, CL
MC
Valid
Valid
Rotate 33 bits (CF, r/m32) right CL times.
REX.W + D3 /3
RCR r/m64, CL
MC
Valid
N.E.
Rotate 65 bits (CF, r/m64) right CL times. Uses
a 6 bit count.
C1 /3 ib
RCR r/m32, imm8
MI
Valid
Valid
Rotate 33 bits (CF, r/m32) right imm8 times.
REX.W + C1 /3 ib
RCR r/m64, imm8
MI
Valid
N.E.
Rotate 65 bits (CF, r/m64) right imm8 times.
Uses a 6 bit count.
D0 /0
ROL r/m8, 1
M1
Valid
Valid
Rotate 8 bits r/m8 left once.
REX + D0 /0
ROL r/m82, 1
M1
Valid
N.E.
Rotate 8 bits r/m8 left once
D2 /0
ROL r/m8, CL
MC
Valid
Valid
Rotate 8 bits r/m8 left CL times.
REX + D2 /0
ROL r/m82, CL
MC
Valid
N.E.
Rotate 8 bits r/m8 left CL times.
C0 /0 ib
ROL r/m8, imm8
MI
Valid
Valid
Rotate 8 bits r/m8 left imm8 times.
4-532
Vol. 2B
RCL/RCR/ROL/ROR—Rotate
INSTRUCTION SET REFERENCE, M-U
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
REX + C0 /0 ib
ROL r/m82, imm8
MI
Valid
N.E.
Rotate 8 bits r/m8 left imm8 times.
D1 /0
ROL r/m16, 1
M1
Valid
Valid
Rotate 16 bits r/m16 left once.
D3 /0
ROL r/m16, CL
MC
Valid
Valid
Rotate 16 bits r/m16 left CL times.
C1 /0 ib
ROL r/m16, imm8
MI
Valid
Valid
Rotate 16 bits r/m16 left imm8 times.
D1 /0
ROL r/m32, 1
M1
Valid
Valid
Rotate 32 bits r/m32 left once.
REX.W + D1 /0
ROL r/m64, 1
M1
Valid
N.E.
Rotate 64 bits r/m64 left once. Uses a 6 bit
count.
D3 /0
ROL r/m32, CL
MC
Valid
Valid
Rotate 32 bits r/m32 left CL times.
REX.W + D3 /0
ROL r/m64, CL
MC
Valid
N.E.
Rotate 64 bits r/m64 left CL times. Uses a 6
bit count.
C1 /0 ib
ROL r/m32, imm8
MI
Valid
Valid
Rotate 32 bits r/m32 left imm8 times.
REX.W + C1 /0 ib
ROL r/m64, imm8
MI
Valid
N.E.
Rotate 64 bits r/m64 left imm8 times. Uses a
6 bit count.
D0 /1
ROR r/m8, 1
M1
Valid
Valid
Rotate 8 bits r/m8 right once.
REX + D0 /1
ROR r/m82, 1
M1
Valid
N.E.
Rotate 8 bits r/m8 right once.
D2 /1
ROR r/m8, CL
MC
Valid
Valid
Rotate 8 bits r/m8 right CL times.
REX + D2 /1
ROR r/m82, CL
MC
Valid
N.E.
Rotate 8 bits r/m8 right CL times.
C0 /1 ib
ROR r/m8, imm8
MI
Valid
Valid
Rotate 8 bits r/m16 right imm8 times.
REX + C0 /1 ib
ROR r/m82, imm8
MI
Valid
N.E.
Rotate 8 bits r/m16 right imm8 times.
D1 /1
ROR r/m16, 1
M1
Valid
Valid
Rotate 16 bits r/m16 right once.
D3 /1
ROR r/m16, CL
MC
Valid
Valid
Rotate 16 bits r/m16 right CL times.
C1 /1 ib
ROR r/m16, imm8
MI
Valid
Valid
Rotate 16 bits r/m16 right imm8 times.
D1 /1
ROR r/m32, 1
M1
Valid
Valid
Rotate 32 bits r/m32 right once.
REX.W + D1 /1
ROR r/m64, 1
M1
Valid
N.E.
Rotate 64 bits r/m64 right once. Uses a 6 bit
count.
D3 /1
ROR r/m32, CL
MC
Valid
Valid
Rotate 32 bits r/m32 right CL times.
REX.W + D3 /1
ROR r/m64, CL
MC
Valid
N.E.
Rotate 64 bits r/m64 right CL times. Uses a 6
bit count.
C1 /1 ib
ROR r/m32, imm8
MI
Valid
Valid
Rotate 32 bits r/m32 right imm8 times.
REX.W + C1 /1 ib
ROR r/m64, imm8
MI
Valid
N.E.
Rotate 64 bits r/m64 right imm8 times. Uses a
6 bit count.
NOTES:
1. See the IA-32 Architecture Compatibility section below.
2. In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M1
ModRM:r/m (w)
1
N/A
N/A
MC
ModRM:r/m (w)
CL
N/A
N/A
MI
ModRM:r/m (w)
imm8
N/A
N/A
RCL/RCR/ROL/ROR—Rotate
Vol. 2B
4-533
INSTRUCTION SET REFERENCE, M-U
Description
Shifts (rotates) the bits of the first operand (destination operand) the number of bit positions specified in the
second operand (count operand) and stores the result in the destination operand. The destination operand can be
a register or a memory location; the count operand is an unsigned integer that can be an immediate or a value in
the CL register. The count is masked to 5 bits (or 6 bits if in 64-bit mode and REX.W = 1).
The rotate left (ROL) and rotate through carry left (RCL) instructions shift all the bits toward more-significant bit
positions, except for the most-significant bit, which is rotated to the least-significant bit location. The rotate right
(ROR) and rotate through carry right (RCR) instructions shift all the bits toward less significant bit positions, except
for the least-significant bit, which is rotated to the most-significant bit location.
The RCL and RCR instructions include the CF flag in the rotation. The RCL instruction shifts the CF flag into the
least-significant bit and shifts the most-significant bit into the CF flag. The RCR instruction shifts the CF flag into the
most-significant bit and shifts the least-significant bit into the CF flag. For the ROL and ROR instructions, the orig-
inal value of the CF flag is not a part of the result, but the CF flag receives a copy of the bit that was shifted from
one end to the other.
The OF flag is defined only for the 1-bit rotates; it is undefined in all other cases (except RCL and RCR instructions
only: a zero-bit rotate does nothing, that is affects no flags). For left rotates, the OF flag is set to the exclusive OR
of the CF bit (after the rotate) and the most-significant bit of the result. For right rotates, the OF flag is set to the
exclusive OR of the two most-significant bits of the result.
In 64-bit mode, using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Use of
REX.W promotes the first operand to 64 bits and causes the count operand to become a 6-bit counter.
IA-32 Architecture Compatibility
The 8086 does not mask the rotation count. However, all other IA-32 processors (starting with the Intel 286
processor) do mask the rotation count to 5 bits, resulting in a maximum count of 31. This masking is done in all
operating modes (including the virtual-8086 mode) to reduce the maximum execution time of the instructions.
Operation
(* RCL and RCR instructions *)
SIZE := OperandSize;
CASE (determine count) OF
SIZE := 8:
tempCOUNT := (COUNT AND 1FH) MOD 9;
SIZE := 16:
tempCOUNT := (COUNT AND 1FH) MOD 17;
SIZE := 32:
tempCOUNT := COUNT AND 1FH;
SIZE := 64:
tempCOUNT := COUNT AND 3FH;
ESAC;
IF OperandSize = 64
THEN COUNTMASK = 3FH;
ELSE COUNTMASK = 1FH;
FI;
(* RCL instruction operation *)
WHILE (tempCOUNT ≠ 0)
DO
tempCF := MSB(DEST);
DEST := (DEST ∗ 2) + CF;
CF := tempCF;
tempCOUNT := tempCOUNT - 1;
OD;
ELIHW;
IF (COUNT & COUNTMASK) = 1
THEN OF := MSB(DEST) XOR CF;
ELSE OF is undefined;
FI;
4-534
Vol. 2B
RCL/RCR/ROL/ROR—Rotate
INSTRUCTION SET REFERENCE, M-U
(* RCR instruction operation *)
IF (COUNT & COUNTMASK) = 1
THEN OF := MSB(DEST) XOR CF;
ELSE OF is undefined;
FI;
WHILE (tempCOUNT ≠ 0)
DO
tempCF := LSB(SRC);
DEST := (DEST / 2) + (CF * 2SIZE);
CF := tempCF;
tempCOUNT := tempCOUNT - 1;
OD;
(* ROL instruction operation *)
tempCOUNT := (COUNT & COUNTMASK) MOD SIZE
WHILE (tempCOUNT ≠ 0)
DO
tempCF := MSB(DEST);
DEST := (DEST ∗ 2) + tempCF;
tempCOUNT := tempCOUNT - 1;
OD;
ELIHW;
IF (COUNT & COUNTMASK) ≠ 0
THEN CF := LSB(DEST);
FI;
IF (COUNT & COUNTMASK) = 1
THEN OF := MSB(DEST) XOR CF;
ELSE OF is undefined;
FI;
(* ROR instruction operation *)
tempCOUNT := (COUNT & COUNTMASK) MOD SIZE
WHILE (tempCOUNT ≠ 0)
DO
tempCF := LSB(SRC);
DEST := (DEST / 2) + (tempCF ∗ 2SIZE);
tempCOUNT := tempCOUNT - 1;
OD;
ELIHW;
IF (COUNT & COUNTMASK) ≠ 0
THEN CF := MSB(DEST);
FI;
IF (COUNT & COUNTMASK) = 1
THEN OF := MSB(DEST) XOR MSB − 1(DEST);
ELSE OF is undefined;
FI;
Flags Affected
For RCL and RCR instructions, a zero-bit rotate does nothing, i.e., affects no flags. For ROL and ROR instructions, if
the masked count is 0, the flags are not affected. If the masked count is 1, then the OF flag is affected, otherwise
(masked count is greater than 1) the OF flag is undefined.
RCL/RCR/ROL/ROR—Rotate
Vol. 2B
4-535
INSTRUCTION SET REFERENCE, M-U
For all instructions, the CF flag is affected when the masked count is non-zero. The SF, ZF, AF, and PF flags are
always unaffected.
Protected Mode Exceptions
#GP(0)
If the source operand is located in a non-writable segment.
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
If the DS, ES, FS, or GS register contains a NULL segment selector.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS
If a memory operand effective address is outside the SS segment limit.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.
#SS(0)
If a memory operand effective address is outside the SS segment limit.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#SS(0)
If a memory address referencing the SS segment is in a non-canonical form.
#GP(0)
If the source operand is located in a nonwritable segment.
If the memory address is in a non-canonical form.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#UD
If the LOCK prefix is used.
4-536
Vol. 2B
RCL/RCR/ROL/ROR—Rotate
INSTRUCTION SET REFERENCE, M-U
RCPPS—Compute Reciprocals of Packed Single Precision Floating-Point Values
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NP 0F 53 /r
RM
V/V
SSE
Computes the approximate reciprocals of the
packed single precision floating-point values in
RCPPS xmm1, xmm2/m128
xmm2/m128 and stores the results in xmm1.
VEX.128.0F.WIG 53 /r
RM
V/V
AVX
Computes the approximate reciprocals of
packed single precision values in xmm2/mem
VRCPPS xmm1, xmm2/m128
and stores the results in xmm1.
VEX.256.0F.WIG 53 /r
RM
V/V
AVX
Computes the approximate reciprocals of
packed single precision values in ymm2/mem
VRCPPS ymm1, ymm2/m256
and stores the results in ymm1.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
Description
Performs a SIMD computation of the approximate reciprocals of the four packed single precision floating-point
values in the source operand (second operand) stores the packed single precision floating-point results in the desti-
nation operand. The source operand can be an XMM register or a 128-bit memory location. The destination
operand is an XMM register. See Figure 10-5 in the Intel® 64 and IA-32 Architectures Software Developer’s
Manual, Volume 1, for an illustration of a SIMD single precision floating-point operation.
The relative error for this approximation is:
|Relative Error| ≤ 1.5 ∗ 2−12
The RCPPS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is a
0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same sign).
Tiny results (see Section 4.9.1.5, “Numeric Underflow Exception (#U)” in Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 1) are always flushed to 0.0, with the sign of the operand. (Input values greater
than or equal to |1.11111111110100000000000B∗2125| are guaranteed to not produce tiny results; input values
less than or equal to |1.00000000000110000000001B*2126| are guaranteed to produce tiny results, which are in
turn flushed to 0.0; and input values in between this range may or may not produce tiny results, depending on the
implementation.) When a source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN
is returned.
In 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers
(XMM8-XMM15).
128-bit Legacy SSE version: The second source can be an XMM register or an 128-bit memory location. The desti-
nation is not distinct from the first source XMM register and the upper bits (MAXVL-1:128) of the corresponding
YMM register destination are unmodified.
VEX.128 encoded version: the first source operand is an XMM register or 128-bit memory location. The destination
operand is an XMM register. The upper bits (MAXVL-1:128) of the corresponding YMM register destination are
zeroed.
VEX.256 encoded version: The first source operand is a YMM register. The second source operand can be a YMM
register or a 256-bit memory location. The destination operand is a YMM register.
Note: In VEX-encoded versions, VEX.vvvv is reserved and must be 1111b, otherwise instructions will #UD.
RCPPS—Compute Reciprocals of Packed Single Precision Floating-Point Values
Vol. 2B
4-537
INSTRUCTION SET REFERENCE, M-U
Operation
RCPPS (128-bit Legacy SSE version)
DEST[31:0] := APPROXIMATE(1/SRC[31:0])
DEST[63:32] := APPROXIMATE(1/SRC[63:32])
DEST[95:64] := APPROXIMATE(1/SRC[95:64])
DEST[127:96] := APPROXIMATE(1/SRC[127:96])
DEST[MAXVL-1:128] (Unmodified)
VRCPPS (VEX.128 encoded version)
DEST[31:0] := APPROXIMATE(1/SRC[31:0])
DEST[63:32] := APPROXIMATE(1/SRC[63:32])
DEST[95:64] := APPROXIMATE(1/SRC[95:64])
DEST[127:96] := APPROXIMATE(1/SRC[127:96])
DEST[MAXVL-1:128] := 0
VRCPPS (VEX.256 encoded version)
DEST[31:0] := APPROXIMATE(1/SRC[31:0])
DEST[63:32] := APPROXIMATE(1/SRC[63:32])
DEST[95:64] := APPROXIMATE(1/SRC[95:64])
DEST[127:96] := APPROXIMATE(1/SRC[127:96])
DEST[159:128] := APPROXIMATE(1/SRC[159:128])
DEST[191:160] := APPROXIMATE(1/SRC[191:160])
DEST[223:192] := APPROXIMATE(1/SRC[223:192])
DEST[255:224] := APPROXIMATE(1/SRC[255:224])
Intel C/C++ Compiler Intrinsic Equivalent
RCCPS:
__m128 _mm_rcp_ps(__m128 a)
RCPPS:
__m256 _mm256_rcp_ps (__m256 a);
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-21, “Type 4 Class Exception Conditions”; additionally:
#UD
If VEX.vvvv ≠ 1111B.
4-538
Vol. 2B
RCPPS—Compute Reciprocals of Packed Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
RCPSS—Compute Reciprocal of Scalar Single Precision Floating-Point Values
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
F3 0F 53 /r
RM
V/V
SSE
Computes the approximate reciprocal of the
scalar single precision floating-point value in
RCPSS xmm1, xmm2/m32
xmm2/m32 and stores the result in xmm1.
VEX.LIG.F3.0F.WIG 53 /r
RVM
V/V
AVX
Computes the approximate reciprocal of the
scalar single precision floating-point value in
VRCPSS xmm1, xmm2, xmm3/m32
xmm3/m32 and stores the result in xmm1.
Also, upper single precision floating-point
values (bits[127:32]) from xmm2 are copied to
xmm1[127:32].
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
RM
ModRM:reg (w)
ModRM:r/m (r)
N/A
N/A
RVM
ModRM:reg (w)
VEX.vvvv (r)
ModRM:r/m (r)
N/A
Description
Computes of an approximate reciprocal of the low single precision floating-point value in the source operand
(second operand) and stores the single precision floating-point result in the destination operand. The source
operand can be an XMM register or a 32-bit memory location. The destination operand is an XMM register. The
three high-order doublewords of the destination operand remain unchanged. See Figure 10-6 in the Intel® 64 and
IA-32 Architectures Software Developer’s Manual, Volume 1, for an illustration of a scalar single precision floating-
point operation.
The relative error for this approximation is:
|Relative Error| ≤ 1.5 ∗ 2−12
The RCPSS instruction is not affected by the rounding control bits in the MXCSR register. When a source value is a
0.0, an ∞ of the sign of the source value is returned. A denormal source value is treated as a 0.0 (of the same sign).
Tiny results (see Section 4.9.1.5, “Numeric Underflow Exception (#U)” in Intel® 64 and IA-32 Architectures Soft-
ware Developer’s Manual, Volume 1) are always flushed to 0.0, with the sign of the operand. (Input values greater
than or equal to |1.11111111110100000000000B∗2125| are guaranteed to not produce tiny results; input values
less than or equal to |1.00000000000110000000001B*2126| are guaranteed to produce tiny results, which are in
turn flushed to 0.0; and input values in between this range may or may not produce tiny results, depending on the
implementation.) When a source value is an SNaN or QNaN, the SNaN is converted to a QNaN or the source QNaN
is returned.
In 64-bit mode, using a REX prefix in the form of REX.R permits this instruction to access additional registers
(XMM8-XMM15).
128-bit Legacy SSE version: The first source operand and the destination operand are the same. Bits (MAXVL-
1:32) of the corresponding YMM destination register remain unchanged.
VEX.128 encoded version: Bits (MAXVL-1:128) of the destination YMM register are zeroed.
Operation
RCPSS (128-bit Legacy SSE version)
DEST[31:0] := APPROXIMATE(1/SRC[31:0])
DEST[MAXVL-1:32] (Unmodified)
RCPSS—Compute Reciprocal of Scalar Single Precision Floating-Point Values
Vol. 2B
4-539
INSTRUCTION SET REFERENCE, M-U
VRCPSS (VEX.128 encoded version)
DEST[31:0] := APPROXIMATE(1/SRC2[31:0])
DEST[127:32] := SRC1[127:32]
DEST[MAXVL-1:128] := 0
Intel C/C++ Compiler Intrinsic Equivalent
RCPSS:
__m128 _mm_rcp_ss(__m128 a)
SIMD Floating-Point Exceptions
None.
Other Exceptions
See Table 2-22, “Type 5 Class Exception Conditions”.
4-540
Vol. 2B
RCPSS—Compute Reciprocal of Scalar Single Precision Floating-Point Values
INSTRUCTION SET REFERENCE, M-U
RDFSBASE/RDGSBASE—Read FS/GS Segment Base
Opcode/
Op/
64/32-
CPUID Fea-
Description
Instruction
En
bit
ture Flag
Mode
F3 0F AE /0
M
V/I
FSGSBASE
Load the 32-bit destination register with the FS
RDFSBASE r32
base address.
F3 REX.W 0F AE /0
M
V/I
FSGSBASE
Load the 64-bit destination register with the FS
RDFSBASE r64
base address.
F3 0F AE /1
M
V/I
FSGSBASE
Load the 32-bit destination register with the GS
RDGSBASE r32
base address.
F3 REX.W 0F AE /1
M
V/I
FSGSBASE
Load the 64-bit destination register with the GS
RDGSBASE r64
base address.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Loads the general-purpose register indicated by the ModR/M:r/m field with the FS or GS segment base address.
The destination operand may be either a 32-bit or a 64-bit general-purpose register. The REX.W prefix indicates the
operand size is 64 bits. If no REX.W prefix is used, the operand size is 32 bits; the upper 32 bits of the source base
address (for FS or GS) are ignored and upper 32 bits of the destination register are cleared.
This instruction is supported only in 64-bit mode.
Operation
DEST := FS/GS segment base address;
Flags Affected
None
C/C++ Compiler Intrinsic Equivalent
RDFSBASE:
unsigned int _readfsbase_u32(void );
RDFSBASE:
unsigned __int64 _readfsbase_u64(void );
RDGSBASE:
unsigned int _readgsbase_u32(void );
RDGSBASE:
unsigned __int64 _readgsbase_u64(void );
Protected Mode Exceptions
#UD
The RDFSBASE and RDGSBASE instructions are not recognized in protected mode.
Real-Address Mode Exceptions
#UD
The RDFSBASE and RDGSBASE instructions are not recognized in real-address mode.
Virtual-8086 Mode Exceptions
#UD
The RDFSBASE and RDGSBASE instructions are not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
#UD
The RDFSBASE and RDGSBASE instructions are not recognized in compatibility mode.
RDFSBASE/RDGSBASE—Read FS/GS Segment Base
Vol. 2B
4-541
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If CR4.FSGSBASE[bit 16] = 0.
If CPUID.07H.0H:EBX.FSGSBASE[bit 0] = 0.
4-542
Vol. 2B
RDFSBASE/RDGSBASE—Read FS/GS Segment Base
INSTRUCTION SET REFERENCE, M-U
RDMSR—Read From Model Specific Register
Opcode1
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 32
RDMSR
ZO
Valid
Valid
Read MSR specified by ECX into EDX:EAX.
NOTES:
1. See the IA-32 Architecture Compatibility section below.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the contents of a 64-bit model specific register (MSR) specified in the ECX register into registers EDX:EAX.
(On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The EDX register
is loaded with the high-order 32 bits of the MSR and the EAX register is loaded with the low-order 32 bits. (On
processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.) If
fewer than 64 bits are implemented in the MSR being read, the values returned to EDX:EAX in unimplemented bit
locations are undefined.
This instruction must be executed at privilege level 0 or in real-address mode; otherwise, a general protection
exception #GP(0) will be generated. Specifying a reserved or unimplemented MSR address in ECX will also cause a
general protection exception.
The MSRs control functions for testability, execution tracing, performance-monitoring, and machine check errors.
Chapter 2, “Model-Specific Registers (MSRs)” of the Intel® 64 and IA-32 Architectures Software Developer’s
Manual, Volume 4, lists all the MSRs that can be read with this instruction and their addresses. Note that each
processor family has its own set of MSRs.
The CPUID instruction should be used to determine whether MSRs are supported (CPUID.01H:EDX[5] = 1) before
using this instruction.
IA-32 Architecture Compatibility
The MSRs and the ability to read them with the RDMSR instruction were introduced into the IA-32 Architecture with
the Pentium processor. Execution of this instruction by an IA-32 processor earlier than the Pentium processor
results in an invalid opcode exception #UD.
See “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in
VMX non-root operation.
Operation
EDX:EAX := MSR[ECX];
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the current privilege level is not 0.
If the value in ECX specifies a reserved or unimplemented MSR address.
#UD
If the LOCK prefix is used.
RDMSR—Read From Model Specific Register
Vol. 2B
4-543
INSTRUCTION SET REFERENCE, M-U
Real-Address Mode Exceptions
#GP
If the value in ECX specifies a reserved or unimplemented MSR address.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
The RDMSR instruction is not recognized in virtual-8086 mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
4-544
Vol. 2B
RDMSR—Read From Model Specific Register
INSTRUCTION SET REFERENCE, M-U
RDPID—Read Processor ID
Opcode/
Op/
64/32-
CPUID
Description
Instruction
En
bit
Feature Flag
Mode
F3 0F C7 /7
R
N.E./V
RDPID
Read IA32_TSC_AUX into r32.
RDPID r32
F3 0F C7 /7
R
V/N.E.
RDPID
Read IA32_TSC_AUX into r64.
RDPID r64
Instruction Operand Encoding1
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
R
ModRM:r/m (w)
N/A
N/A
N/A
Description
Reads the value of the IA32_TSC_AUX MSR (address C0000103H) into the destination register. The value of CS.D
and operand-size prefixes (66H and REX.W) do not affect the behavior of the RDPID instruction.
Operation
DEST := IA32_TSC_AUX
Flags Affected
None.
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.7H.0:ECX.RDPID[bit 22] = 0.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
1.ModRM.MOD = 011B required
RDPID—Read Processor ID
Vol. 2B
4-545
INSTRUCTION SET REFERENCE, M-U
RDPKRU—Read Protection Key Rights for User Pages
Opcode*
Instruction
Op/
64/32bit
CPUID
Description
En
Mode
Feature
Support
Flag
NP 0F 01 EE
RDPKRU
ZO
V/V
OSPKE
Reads PKRU into EAX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the value of PKRU into EAX and clears EDX. ECX must be 0 when RDPKRU is executed; otherwise, a general-
protection exception (#GP) occurs.
RDPKRU can be executed only if CR4.PKE = 1; otherwise, an invalid-opcode exception (#UD) occurs. Software can
discover the value of CR4.PKE by examining CPUID.(EAX=07H,ECX=0H):ECX.OSPKE [bit 4].
On processors that support the Intel 64 Architecture, the high-order 32-bits of RCX are ignored and the high-order
32-bits of RDX and RAX are cleared.
Operation
IF (ECX = 0)
THEN
EAX := PKRU;
EDX := 0;
ELSE #GP(0);
FI;
Flags Affected
None.
C/C++ Compiler Intrinsic Equivalent
RDPKRU:
uint32_t _rdpkru_u32(void);
Protected Mode Exceptions
#GP(0)
If ECX ≠ 0.
#UD
If the LOCK prefix is used.
If CR4.PKE = 0.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
4-546
Vol. 2B
RDPKRU—Read Protection Key Rights for User Pages
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDPKRU—Read Protection Key Rights for User Pages
Vol. 2B
4-547
INSTRUCTION SET REFERENCE, M-U
RDPMC—Read Performance-Monitoring Counters
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 33
RDPMC
ZO
Valid
Valid
Read performance-monitoring counter
specified by ECX into EDX:EAX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the contents of the performance monitoring counter (PMC) specified in ECX register into registers EDX:EAX.
(On processors that support the Intel 64 architecture, the high-order 32 bits of RCX are ignored.) The EDX register
is loaded with the high-order 32 bits of the PMC and the EAX register is loaded with the low-order 32 bits. (On
processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.) If
fewer than 64 bits are implemented in the PMC being read, unimplemented bits returned to EDX:EAX will have
value zero.
The width of PMCs on processors supporting architectural performance monitoring (CPUID.0AH:EAX[7:0] ≠ 0) are
reported by CPUID.0AH:EAX[23:16]. On processors that do not support architectural performance monitoring
(CPUID.0AH:EAX[7:0]=0), the width of general-purpose performance PMCs is 40 bits, while the widths of special-
purpose PMCs are implementation specific.
Use of ECX to specify a PMC depends on whether the processor supports architectural performance monitoring:
• If the processor does not support architectural performance monitoring (CPUID.0AH:EAX[7:0]=0), ECX[30:0]
specifies the index of the PMC to be read. Setting ECX[31] selects “fast” read mode if supported. In this mode,
RDPMC returns bits 31:0 of the PMC in EAX while clearing EDX to zero.
• If the processor does support architectural performance monitoring (CPUID.0AH:EAX[7:0] ≠ 0), ECX[31:16]
specifies type of PMC while ECX[15:0] specifies the index of the PMC to be read within that type. The following
PMC types are currently defined:
— General-purpose counters use type 0. The index x (to read IA32_PMCx) must be less than the value
enumerated by CPUID.0AH.EAX[15:8] (thus ECX[15:8] must be zero).
— Fixed-function counters use type 4000H. The index x (to read IA32_FIXED_CTRx) can be used if either
CPUID.0AH.EDX[4:0] > x or CPUID.0AH.ECX[x] = 1 (thus ECX[15:5] must be 0).
— Performance metrics use type 2000H. This type can be used only if
IA32_PERF_CAPABILITIES.PERF_METRICS_AVAILABLE[bit 15]=1. For this type, the index in ECX[15:0] is
implementation specific.
Specifying an unsupported PMC encoding will cause a general protection exception #GP(0). For PMC details see
Chapter 20, “Performance Monitoring,” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual,
Volume 3B.
When in protected or virtual 8086 mode, the Performance-monitoring Counters Enabled (PCE) flag in register
CR4 restricts the use of the RDPMC instruction. When the PCE flag is set, the RDPMC instruction can be executed at
any privilege level; when the flag is clear, the instruction can only be executed at privilege level 0. (When in real-
address mode, the RDPMC instruction is always enabled.) The PMCs can also be read with the RDMSR instruction,
when executing at privilege level 0.
The RDPMC instruction is not a serializing instruction; that is, it does not imply that all the events caused by the
preceding instructions have been completed or that events caused by subsequent instructions have not begun. If
an exact event count is desired, software must insert a serializing instruction (such as the CPUID instruction)
before and/or after the RDPMC instruction.
Performing back-to-back fast reads are not guaranteed to be monotonic. To guarantee monotonicity on back-to-
back reads, a serializing instruction must be placed between the two RDPMC instructions.
4-548
Vol. 2B
RDPMC—Read Performance-Monitoring Counters
INSTRUCTION SET REFERENCE, M-U
The RDPMC instruction can execute in 16-bit addressing mode or virtual-8086 mode; however, the full contents of
the ECX register are used to select the PMC, and the event count is stored in the full EAX and EDX registers. The
RDPMC instruction was introduced into the IA-32 Architecture in the Pentium Pro processor and the Pentium
processor with MMX technology. The earlier Pentium processors have PMCs, but they must be read with the RDMSR
instruction.
Operation
MSCB = Most Significant Counter Bit (* Model-specific *)
IF (((CR4.PCE = 1) or (CPL = 0) or (CR0.PE = 0)) and (ECX indicates a supported counter))
THEN
EAX := counter[31:0];
EDX := ZeroExtend(counter[MSCB:32]);
ELSE (* ECX is not valid or CR4.PCE is 0 and CPL is 1, 2, or 3 and CR0.PE is 1 *)
#GP(0);
FI;
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the current privilege level is not 0 and the PCE flag in the CR4 register is clear.
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#GP
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If the PCE flag in the CR4 register is clear.
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
#GP(0)
If the current privilege level is not 0 and the PCE flag in the CR4 register is clear.
If an invalid performance counter index is specified.
#UD
If the LOCK prefix is used.
RDPMC—Read Performance-Monitoring Counters
Vol. 2B
4-549
INSTRUCTION SET REFERENCE, M-U
RDRAND—Read Random Number
Opcode*/
Op/
64/32 bit
CPUID
Description
Instruction
En
Mode
Feature
Support
Flag
NFx 0F C7 /6
M
V/V
RDRAND
Read a 16-bit random number and store in the
destination register.
RDRAND r16
NFx 0F C7 /6
M
V/V
RDRAND
Read a 32-bit random number and store in the
destination register.
RDRAND r32
NFx REX.W + 0F C7 /6
M
V/I
RDRAND
Read a 64-bit random number and store in the
destination register.
RDRAND r64
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Loads a hardware generated random value and store it in the destination register. The size of the random value is
determined by the destination register size and operating mode. The Carry Flag indicates whether a random value
is available at the time the instruction is executed. CF=1 indicates that the data in the destination is valid. Other-
wise CF=0 and the data in the destination operand will be returned as zeros for the specified width. All other flags
are forced to 0 in either situation. Software must check the state of CF=1 for determining if a valid random value
has been returned, otherwise it is expected to loop and retry execution of RDRAND (see Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 1, Section 7.3.17, “Random Number Generator Instructions”).
This instruction is available at all privilege levels.
In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.B permits
access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bit oper-
ands. See the summary chart at the beginning of this section for encoding data and limits.
Operation
IF HW_RND_GEN.ready = 1
THEN
CASE of
osize is 64: DEST[63:0] := HW_RND_GEN.data;
osize is 32: DEST[31:0] := HW_RND_GEN.data;
osize is 16: DEST[15:0] := HW_RND_GEN.data;
ESAC
CF := 1;
ELSE
CASE of
osize is 64: DEST[63:0] := 0;
osize is 32: DEST[31:0] := 0;
osize is 16: DEST[15:0] := 0;
ESAC
CF := 0;
FI
OF, SF, ZF, AF, PF := 0;
Flags Affected
The CF flag is set according to the result (see the “Operation” section above). The OF, SF, ZF, AF, and PF flags are
set to 0.
4-550
Vol. 2B
RDRAND—Read Random Number
INSTRUCTION SET REFERENCE, M-U
Intel C/C++ Compiler Intrinsic Equivalent
RDRAND:
int _rdrand16_step( unsigned short * );
RDRAND:
int _rdrand32_step( unsigned int * );
RDRAND:
int _rdrand64_step( unsigned __int64 *);
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.01H:ECX.RDRAND[bit 30] = 0.
Real-Address Mode Exceptions
Same exceptions as in protected mode.
Virtual-8086 Mode Exceptions
Same exceptions as in protected mode.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDRAND—Read Random Number
Vol. 2B
4-551
INSTRUCTION SET REFERENCE, M-U
RDSEED—Read Random SEED
Opcode/
Op/
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
NFx 0F C7 /7
M
V/V
RDSEED
Read a 16-bit NIST SP800-90B & C compliant random value and
RDSEED r16
store in the destination register.
NFx 0F C7 /7
M
V/V
RDSEED
Read a 32-bit NIST SP800-90B & C compliant random value and
RDSEED r32
store in the destination register.
NFx REX.W + 0F C7 /7
M
V/I
RDSEED
Read a 64-bit NIST SP800-90B & C compliant random value and
RDSEED r64
store in the destination register.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
M
ModRM:r/m (w)
N/A
N/A
N/A
Description
Loads a hardware generated random value and store it in the destination register. The random value is generated
from an Enhanced NRBG (Non Deterministic Random Bit Generator) that is compliant to NIST SP800-90B and NIST
SP800-90C in the XOR construction mode. The size of the random value is determined by the destination register
size and operating mode. The Carry Flag indicates whether a random value is available at the time the instruction
is executed. CF=1 indicates that the data in the destination is valid. Otherwise CF=0 and the data in the destination
operand will be returned as zeros for the specified width. All other flags are forced to 0 in either situation. Software
must check the state of CF=1 for determining if a valid random seed value has been returned, otherwise it is
expected to loop and retry execution of RDSEED (see Section 1.2).
The RDSEED instruction is available at all privilege levels. The RDSEED instruction executes normally either inside
or outside a transaction region.
In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.B permits
access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bit oper-
ands. See the summary chart at the beginning of this section for encoding data and limits.
Operation
IF HW_NRND_GEN.ready = 1
THEN
CASE of
osize is 64: DEST[63:0] := HW_NRND_GEN.data;
osize is 32: DEST[31:0] := HW_NRND_GEN.data;
osize is 16: DEST[15:0] := HW_NRND_GEN.data;
ESAC;
CF := 1;
ELSE
CASE of
osize is 64: DEST[63:0] := 0;
osize is 32: DEST[31:0] := 0;
osize is 16: DEST[15:0] := 0;
ESAC;
CF := 0;
FI;
OF, SF, ZF, AF, PF := 0;
Flags Affected
4-552
Vol. 2B
RDSEED—Read Random SEED
INSTRUCTION SET REFERENCE, M-U
The CF flag is set according to the result (see the "Operation" section above). The OF, SF, ZF, AF, and PF flags
are set to 0.
C/C++ Compiler Intrinsic Equivalent
RDSEED int _rdseed16_step( unsigned short * );
RDSEED int _rdseed32_step( unsigned int * );
RDSEED int _rdseed64_step( unsigned __int64 *);
Protected Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
Virtual-8086 Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
Compatibility Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
64-Bit Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.(EAX=07H, ECX=0H):EBX.RDSEED[bit 18] = 0.
RDSEED—Read Random SEED
Vol. 2B
4-553
INSTRUCTION SET REFERENCE, M-U
RDSSPD/RDSSPQ—Read Shadow Stack Pointer
Opcode/
Op/
64/32
CPUID
Description
Instruction
En
bit Mode
Feature
Support
Flag
F3 0F 1E /1 (mod=11)
R
V/V
CET_SS
Copy low 32 bits of shadow stack pointer (SSP) to r32.
RDSSPD r32
F3 REX.W 0F 1E /1 (mod=11)
R
V/N.E.
CET_SS
Copies shadow stack pointer (SSP) to r64.
RDSSPQ r64
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
R
ModRM:r/m (w)
N/A
N/A
N/A
Description
Copies the current shadow stack pointer (SSP) register to the register destination. This opcode is a NOP when CET
shadow stacks are not enabled and on processors that do not support CET.
Operation
IF CPL = 3
IF CR4.CET & IA32_U_CET.SH_STK_EN
IF (operand size is 64 bit)
THEN
Dest := SSP;
ELSE
Dest := SSP[31:0];
FI;
FI;
ELSE
IF CR4.CET & IA32_S_CET.SH_STK_EN
IF (operand size is 64 bit)
THEN
Dest := SSP;
ELSE
Dest := SSP[31:0];
FI;
FI;
FI;
Flags Affected
None.
C/C++ Compiler Intrinsic Equivalent
RDSSPD
__int32 _rdsspd_i32(void);
RDSSPQ
__int64 _rdsspq_i64(void);
Protected Mode Exceptions
None.
4-554
Vol. 2B
RDSSPD/RDSSPQ—Read Shadow Stack Pointer
INSTRUCTION SET REFERENCE, M-U
Real-Address Mode Exceptions
None.
Virtual-8086 Mode Exceptions
None.
Compatibility Mode Exceptions
None.
64-Bit Mode Exceptions
None.
RDSSPD/RDSSPQ—Read Shadow Stack Pointer
Vol. 2B
4-555
INSTRUCTION SET REFERENCE, M-U
RDTSC—Read Time-Stamp Counter
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 31
RDTSC
ZO
Valid
Valid
Read time-stamp counter into EDX:EAX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers. The EDX
register is loaded with the high-order 32 bits of the MSR and the EAX register is loaded with the low-order 32 bits.
(On processors that support the Intel 64 architecture, the high-order 32 bits of each of RAX and RDX are cleared.)
The processor monotonically increments the time-stamp counter MSR every clock cycle and resets it to 0 whenever
the processor is reset. See “Time Stamp Counter” in Chapter 18 of the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 3B, for specific details of the time stamp counter behavior.
The time stamp disable (TSD) flag in register CR4 restricts the use of the RDTSC instruction as follows. When the
flag is clear, the RDTSC instruction can be executed at any privilege level; when the flag is set, the instruction can
only be executed at privilege level 0.
The time-stamp counter can also be read with the RDMSR instruction, when executing at privilege level 0.
The RDTSC instruction is not a serializing instruction. It does not necessarily wait until all previous instructions
have been executed before reading the counter. Similarly, subsequent instructions may begin execution before the
read operation is performed. The following items may guide software seeking to order executions of RDTSC:
• If software requires RDTSC to be executed only after all previous instructions have executed and all previous
loads are globally visible,1 it can execute LFENCE immediately before RDTSC.
• If software requires RDTSC to be executed only after all previous instructions have executed and all previous
loads and stores are globally visible, it can execute the sequence MFENCE;LFENCE immediately before RDTSC.
• If software requires RDTSC to be executed prior to execution of any subsequent instruction (including any
memory accesses), it can execute the sequence LFENCE immediately after RDTSC.
This instruction was introduced by the Pentium processor.
See “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in
VMX non-root operation.
Operation
IF (CR4.TSD = 0) or (CPL = 0) or (CR0.PE = 0)
THEN EDX:EAX := TimeStampCounter;
ELSE (* CR4.TSD = 1 and (CPL = 1, 2, or 3) and CR0.PE = 1 *)
#GP(0);
FI;
Flags Affected
None.
1. A load is considered to become globally visible when the value to be loaded is determined.
4-556
Vol. 2B
RDTSC—Read Time-Stamp Counter
INSTRUCTION SET REFERENCE, M-U
Protected Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set and the CPL is greater than 0.
#UD
If the LOCK prefix is used.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
Virtual-8086 Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set.
#UD
If the LOCK prefix is used.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDTSC—Read Time-Stamp Counter
Vol. 2B
4-557
INSTRUCTION SET REFERENCE, M-U
RDTSCP—Read Time-Stamp Counter and Processor ID
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
0F 01 F9
RDTSCP
ZO
Valid
Valid
Read 64-bit time-stamp counter and
IA32_TSC_AUX value into EDX:EAX and ECX.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Reads the current value of the processor’s time-stamp counter (a 64-bit MSR) into the EDX:EAX registers and also
reads the value of the IA32_TSC_AUX MSR (address C0000103H) into the ECX register. The EDX register is loaded
with the high-order 32 bits of the IA32_TSC MSR; the EAX register is loaded with the low-order 32 bits of the
IA32_TSC MSR; and the ECX register is loaded with the low-order 32-bits of IA32_TSC_AUX MSR. On processors
that support the Intel 64 architecture, the high-order 32 bits of each of RAX, RDX, and RCX are cleared.
The processor monotonically increments the time-stamp counter MSR every clock cycle and resets it to 0 whenever
the processor is reset. See “Time Stamp Counter” in Chapter 18 of the Intel® 64 and IA-32 Architectures Software
Developer’s Manual, Volume 3B, for specific details of the time stamp counter behavior.
The time stamp disable (TSD) flag in register CR4 restricts the use of the RDTSCP instruction as follows. When the
flag is clear, the RDTSCP instruction can be executed at any privilege level; when the flag is set, the instruction can
only be executed at privilege level 0.
The RDTSCP instruction is not a serializing instruction, but it does wait until all previous instructions have executed
and all previous loads are globally visible.1 But it does not wait for previous stores to be globally visible, and subse-
quent instructions may begin execution before the read operation is performed. The following items may guide
software seeking to order executions of RDTSCP:
• If software requires RDTSCP to be executed only after all previous stores are globally visible, it can execute
MFENCE immediately before RDTSCP.
• If software requires RDTSCP to be executed prior to execution of any subsequent instruction (including any
memory accesses), it can execute LFENCE immediately after RDTSCP.
See “Changes to Instruction Behavior in VMX Non-Root Operation” in Chapter 26 of the Intel® 64 and IA-32 Archi-
tectures Software Developer’s Manual, Volume 3C, for more information about the behavior of this instruction in
VMX non-root operation.
Operation
IF (CR4.TSD = 0) or (CPL = 0) or (CR0.PE = 0)
THEN
EDX:EAX := TimeStampCounter;
ECX := IA32_TSC_AUX[31:0];
ELSE (* CR4.TSD = 1 and (CPL = 1, 2, or 3) and CR0.PE = 1 *)
#GP(0);
FI;
Flags Affected
None.
1. A load is considered to become globally visible when the value to be loaded is determined.
4-558
Vol. 2B
RDTSCP—Read Time-Stamp Counter and Processor ID
INSTRUCTION SET REFERENCE, M-U
Protected Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set and the CPL is greater than 0.
#UD
If the LOCK prefix is used.
If CPUID.80000001H:EDX.RDTSCP[bit 27] = 0.
Real-Address Mode Exceptions
#UD
If the LOCK prefix is used.
If CPUID.80000001H:EDX.RDTSCP[bit 27] = 0.
Virtual-8086 Mode Exceptions
#GP(0)
If the TSD flag in register CR4 is set.
#UD
If the LOCK prefix is used.
If CPUID.80000001H:EDX.RDTSCP[bit 27] = 0.
Compatibility Mode Exceptions
Same exceptions as in protected mode.
64-Bit Mode Exceptions
Same exceptions as in protected mode.
RDTSCP—Read Time-Stamp Counter and Processor ID
Vol. 2B
4-559
INSTRUCTION SET REFERENCE, M-U
REP/REPE/REPZ/REPNE/REPNZ—Repeat String Operation Prefix
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
F3 6C
REP INS m8, DX
ZO
Valid
Valid
Input (E)CX bytes from port DX into ES:[(E)DI].
F3 6C
REP INS m8, DX
ZO
Valid
N.E.
Input RCX bytes from port DX into [RDI].
F3 6D
REP INS m16, DX
ZO
Valid
Valid
Input (E)CX words from port DX into ES:[(E)DI.]
F3 6D
REP INS m32, DX
ZO
Valid
Valid
Input (E)CX doublewords from port DX into
ES:[(E)DI].
F3 6D
REP INS r/m32, DX
ZO
Valid
N.E.
Input RCX default size from port DX into [RDI].
F3 A4
REP MOVS m8, m8
ZO
Valid
Valid
Move (E)CX bytes from DS:[(E)SI] to ES:[(E)DI].
F3 REX.W A4
REP MOVS m8, m8
ZO
Valid
N.E.
Move RCX bytes from [RSI] to [RDI].
F3 A5
REP MOVS m16, m16
ZO
Valid
Valid
Move (E)CX words from DS:[(E)SI] to ES:[(E)DI].
F3 A5
REP MOVS m32, m32
ZO
Valid
Valid
Move (E)CX doublewords from DS:[(E)SI] to
ES:[(E)DI].
F3 REX.W A5
REP MOVS m64, m64
ZO
Valid
N.E.
Move RCX quadwords from [RSI] to [RDI].
F3 6E
REP OUTS DX, r/m8
ZO
Valid
Valid
Output (E)CX bytes from DS:[(E)SI] to port DX.
F3 REX.W 6E
REP OUTS DX, r/m81
ZO
Valid
N.E.
Output RCX bytes from [RSI] to port DX.
F3 6F
REP OUTS DX, r/m16
ZO
Valid
Valid
Output (E)CX words from DS:[(E)SI] to port DX.
F3 6F
REP OUTS DX, r/m32
ZO
Valid
Valid
Output (E)CX doublewords from DS:[(E)SI] to
port DX.
F3 REX.W 6F
REP OUTS DX, r/m32
ZO
Valid
N.E.
Output RCX default size from [RSI] to port DX.
F3 AC
REP LODS AL
ZO
Valid
Valid
Load (E)CX bytes from DS:[(E)SI] to AL.
F3 REX.W AC
REP LODS AL
ZO
Valid
N.E.
Load RCX bytes from [RSI] to AL.
F3 AD
REP LODS AX
ZO
Valid
Valid
Load (E)CX words from DS:[(E)SI] to AX.
F3 AD
REP LODS EAX
ZO
Valid
Valid
Load (E)CX doublewords from DS:[(E)SI] to
EAX.
F3 REX.W AD
REP LODS RAX
ZO
Valid
N.E.
Load RCX quadwords from [RSI] to RAX.
F3 AA
REP STOS m8
ZO
Valid
Valid
Fill (E)CX bytes at ES:[(E)DI] with AL.
F3 REX.W AA
REP STOS m8
ZO
Valid
N.E.
Fill RCX bytes at [RDI] with AL.
F3 AB
REP STOS m16
ZO
Valid
Valid
Fill (E)CX words at ES:[(E)DI] with AX.
F3 AB
REP STOS m32
ZO
Valid
Valid
Fill (E)CX doublewords at ES:[(E)DI] with EAX.
F3 REX.W AB
REP STOS m64
ZO
Valid
N.E.
Fill RCX quadwords at [RDI] with RAX.
F3 A6
REPE CMPS m8, m8
ZO
Valid
Valid
Find nonmatching bytes in ES:[(E)DI] and
DS:[(E)SI].
F3 REX.W A6
REPE CMPS m8, m8
ZO
Valid
N.E.
Find non-matching bytes in [RDI] and [RSI].
F3 A7
REPE CMPS m16, m16
ZO
Valid
Valid
Find nonmatching words in ES:[(E)DI] and
DS:[(E)SI].
F3 A7
REPE CMPS m32, m32
ZO
Valid
Valid
Find nonmatching doublewords in ES:[(E)DI]
and DS:[(E)SI].
F3 REX.W A7
REPE CMPS m64, m64
ZO
Valid
N.E.
Find non-matching quadwords in [RDI] and
[RSI].
F3 AE
REPE SCAS m8
ZO
Valid
Valid
Find non-AL byte starting at ES:[(E)DI].
F3 REX.W AE
REPE SCAS m8
ZO
Valid
N.E.
Find non-AL byte starting at [RDI].
F3 AF
REPE SCAS m16
ZO
Valid
Valid
Find non-AX word starting at ES:[(E)DI].
F3 AF
REPE SCAS m32
ZO
Valid
Valid
Find non-EAX doubleword starting at
ES:[(E)DI].
4-560
Vol. 2B
REP/REPE/REPZ/REPNE/REPNZ—Repeat String Operation Prefix
INSTRUCTION SET REFERENCE, M-U
Opcode
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
F3 REX.W AF
REPE SCAS m64
ZO
Valid
N.E.
Find non-RAX quadword starting at [RDI].
F2 A6
REPNE CMPS m8, m8
ZO
Valid
Valid
Find matching bytes in ES:[(E)DI] and DS:[(E)SI].
F2 REX.W A6
REPNE CMPS m8, m8
ZO
Valid
N.E.
Find matching bytes in [RDI] and [RSI].
F2 A7
REPNE CMPS m16, m16
ZO
Valid
Valid
Find matching words in ES:[(E)DI] and
DS:[(E)SI].
F2 A7
REPNE CMPS m32, m32
ZO
Valid
Valid
Find matching doublewords in ES:[(E)DI] and
DS:[(E)SI].
F2 REX.W A7
REPNE CMPS m64, m64
ZO
Valid
N.E.
Find matching doublewords in [RDI] and [RSI].
F2 AE
REPNE SCAS m8
ZO
Valid
Valid
Find AL, starting at ES:[(E)DI].
F2 REX.W AE
REPNE SCAS m8
ZO
Valid
N.E.
Find AL, starting at [RDI].
F2 AF
REPNE SCAS m16
ZO
Valid
Valid
Find AX, starting at ES:[(E)DI].
F2 AF
REPNE SCAS m32
ZO
Valid
Valid
Find EAX, starting at ES:[(E)DI].
F2 REX.W AF
REPNE SCAS m64
ZO
Valid
N.E.
Find RAX, starting at [RDI].
NOTES:
1. In 64-bit mode, r/m8 can not be encoded to access the following byte registers if a REX prefix is used: AH, BH, CH, DH.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
Description
Repeats a string instruction the number of times specified in the count register or until the indicated condition of
the ZF flag is no longer met. The REP (repeat), REPE (repeat while equal), REPNE (repeat while not equal), REPZ
(repeat while zero), and REPNZ (repeat while not zero) mnemonics are prefixes that can be added to one of the
string instructions. The REP prefix can be added to the INS, OUTS, MOVS, LODS, and STOS instructions, and the
REPE, REPNE, REPZ, and REPNZ prefixes can be added to the CMPS and SCAS instructions. (The REPZ and REPNZ
prefixes are synonymous forms of the REPE and REPNE prefixes, respectively.) The F3H prefix is defined for the
following instructions and undefined for the rest:
• F3H as REP/REPE/REPZ for string and input/output instruction.
• F3H is a mandatory prefix for POPCNT, LZCNT, and ADOX.
The REP prefixes apply only to one string instruction at a time. To repeat a block of instructions, use the LOOP
instruction or another looping construct. All of these repeat prefixes cause the associated instruction to be
repeated until the count in register is decremented to 0. See Table 4-22.
Table 4-22. Repeat Prefixes
Repeat Prefix
Termination Condition 1*
Termination Condition 2
REP
RCX or (E)CX = 0
None
REPE/REPZ
RCX or (E)CX = 0
ZF = 0
REPNE/REPNZ
RCX or (E)CX = 0
ZF = 1
NOTES:
* Count register is CX, ECX or RCX by default, depending on attributes of the operating modes.
REP/REPE/REPZ/REPNE/REPNZ—Repeat String Operation Prefix
Vol. 2B
4-561
INSTRUCTION SET REFERENCE, M-U
The REPE, REPNE, REPZ, and REPNZ prefixes also check the state of the ZF flag after each iteration and terminate
the repeat loop if the ZF flag is not in the specified state. When both termination conditions are tested, the cause
of a repeat termination can be determined either by testing the count register with a JECXZ instruction or by testing
the ZF flag (with a JZ, JNZ, or JNE instruction).
When the REPE/REPZ and REPNE/REPNZ prefixes are used, the ZF flag does not require initialization because both
the CMPS and SCAS instructions affect the ZF flag according to the results of the comparisons they make.
A repeating string operation can be suspended by an exception or interrupt. When this happens, the state of the
registers is preserved to allow the string operation to be resumed upon a return from the exception or interrupt
handler. The source and destination registers point to the next string elements to be operated on, the EIP register
points to the string instruction, and the ECX register has the value it held following the last successful iteration of
the instruction. This mechanism allows long string operations to proceed without affecting the interrupt response
time of the system.
When a fault occurs during the execution of a CMPS or SCAS instruction that is prefixed with REPE or REPNE, the
EFLAGS value is restored to the state prior to the execution of the instruction. Since the SCAS and CMPS instruc-
tions do not use EFLAGS as an input, the processor can resume the instruction after the page fault handler.
Use the REP INS and REP OUTS instructions with caution. Not all I/O ports can handle the rate at which these
instructions execute. Note that a REP STOS instruction is the fastest way to initialize a large block of memory.
In 64-bit mode, the operand size of the count register is associated with the address size attribute. Thus the default
count register is RCX; REX.W has no effect on the address size and the count register. In 64-bit mode, if 67H is used
to override address size attribute, the count register is ECX and any implicit source/destination operand will use the
corresponding 32-bit index register. See the summary chart at the beginning of this section for encoding data and
limits.
REP INS may read from the I/O port without writing to the memory location if an exception or VM exit occurs due
to the write (e.g., #PF). If this would be problematic, for example because the I/O port read has side-effects, soft-
ware should ensure the write to the memory location does not cause an exception or VM exit.
Operation
IF AddressSize = 16
THEN
Use CX for CountReg;
Implicit Source/Dest operand for memory use of SI/DI;
ELSE IF AddressSize = 64
THEN Use RCX for CountReg;
Implicit Source/Dest operand for memory use of RSI/RDI;
ELSE
Use ECX for CountReg;
Implicit Source/Dest operand for memory use of ESI/EDI;
FI;
WHILE CountReg ≠ 0
DO
Service pending interrupts (if any);
Execute associated string instruction;
CountReg := (CountReg - 1);
IF CountReg = 0
THEN exit WHILE loop; FI;
IF (Repeat prefix is REPZ or REPE) and (ZF = 0)
or (Repeat prefix is REPNZ or REPNE) and (ZF = 1)
THEN exit WHILE loop; FI;
OD;
Flags Affected
None; however, the CMPS and SCAS instructions do set the status flags in the EFLAGS register.
4-562
Vol. 2B
REP/REPE/REPZ/REPNE/REPNZ—Repeat String Operation Prefix
INSTRUCTION SET REFERENCE, M-U
Exceptions (All Operating Modes)
Exceptions may be generated by an instruction associated with the prefix.
64-Bit Mode Exceptions
#GP(0)
If the memory address is in a non-canonical form.
REP/REPE/REPZ/REPNE/REPNZ—Repeat String Operation Prefix
Vol. 2B
4-563
INSTRUCTION SET REFERENCE, M-U
RET—Return From Procedure
Opcode*
Instruction
Op/
64-Bit
Compat/
Description
En
Mode
Leg Mode
C3
RET
ZO
Valid
Valid
Near return to calling procedure.
CB
RET
ZO
Valid
Valid
Far return to calling procedure.
C2 iw
RET imm16
I
Valid
Valid
Near return to calling procedure and pop
imm16 bytes from stack.
CA iw
RET imm16
I
Valid
Valid
Far return to calling procedure and pop imm16
bytes from stack.
Instruction Operand Encoding
Op/En
Operand 1
Operand 2
Operand 3
Operand 4
ZO
N/A
N/A
N/A
N/A
I
imm16
N/A
N/A
N/A
Description
Transfers program control to a return address located on the top of the stack. The address is usually placed on the
stack by a CALL instruction, and the return is made to the instruction that follows the CALL instruction.
The optional source operand specifies the number of stack bytes to be released after the return address is popped;
the default is none. This operand can be used to release parameters from the stack that were passed to the called
procedure and are no longer needed. It must be used when the CALL instruction used to switch to a new procedure
uses a call gate with a non-zero word count to access the new procedure. Here, the source operand for the RET
instruction must specify the same number of bytes as is specified in the word count field of the call gate.
The RET instruction can be used to execute three different types of returns:
• Near return — A return to a calling procedure within the current code segment (the segment currently pointed
to by the CS register), sometimes referred to as an intrasegment return.
• Far return — A return to a calling procedure located in a different segment than the current code segment,
sometimes referred to as an intersegment return.
• Inter-privilege-level far return — A far return to a different privilege level than that of the currently
executing program or procedure.
The inter-privilege-level return type can only be executed in protected mode. See the section titled “Calling Proce-
dures Using Call and RET” in Chapter 6 of the Intel® 64 and IA-32 Architectures Software Developer’s Manual,
Volume 1, for detailed information on near, far, and inter-privilege-level returns.
When executing a near return, the processor pops the return instruction pointer (offset) from the top of the stack
into the EIP register and begins program execution at the new instruction pointer. The CS register is unchanged.
When executing a far return, the processor pops the return instruction pointer from the top of the stack into the EIP
register, then pops the segment selector from the top of the stack into the CS register. The processor then begins
program execution in the new code segment at the new instruction pointer.
The mechanics of an inter-privilege-level far return are similar to an intersegment return, except that the processor
examines the privilege levels and access rights of the code and stack segments being returned to determine if the
control transfer is allowed to be made. The DS, ES, FS, and GS segment registers are cleared by the RET instruction
during an inter-privilege-level return if they refer to segments that are not allowed to be accessed at the new priv-
ilege level. Since a stack switch also occurs on an inter-privilege level return, the ESP and SS registers are loaded
from the stack.
If parameters are passed to the called procedure during an inter-privilege level call, the optional source operand
must be used with the RET instruction to release the parameters on the return. Here, the parameters are released
both from the called procedure’s stack and the calling procedure’s stack (that is, the stack being returned to).
In 64-bit mode, the default operation size of this instruction is the stack-address size, i.e., 64 bits. This applies to
near returns, not far returns; the default operation size of far returns is 32 bits.
4-564
Vol. 2B
RET—Return From Procedure
INSTRUCTION SET REFERENCE, M-U
Refer to Chapter 6, “Procedure Calls, Interrupts, and Exceptions” and Chapter 17, “Control-Flow Enforcement
Technology (CET)” in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1 for CET
details.
Instruction ordering. Instructions following a far return may be fetched from memory before earlier instructions
complete execution, but they will not execute (even speculatively) until all instructions prior to the far return have
completed execution (the later instructions may execute before data stored by the earlier instructions have
become globally visible).
Unlike near indirect CALL and near indirect JMP, the processor will not speculatively execute the next sequential
instruction after a near RET unless that instruction is also the target of a jump or is a target in a branch predictor.
Operation
(* Near return *)
IF instruction = near return
THEN;
IF OperandSize = 32
THEN
IF top 4 bytes of stack not within stack limits
THEN #SS(0); FI;
EIP := Pop();
IF ShadowStackEnabled(CPL)
tempSsEIP = ShadowStackPop4B();
IF EIP != TempSsEIP
THEN #CP(NEAR_RET); FI;
FI;
ELSE
IF OperandSize = 64
THEN
IF top 8 bytes of stack not within stack limits
THEN #SS(0); FI;
RIP := Pop();
IF ShadowStackEnabled(CPL)
tempSsEIP = ShadowStackPop8B();
IF RIP != tempSsEIP
THEN #CP(NEAR_RET); FI;
FI;
ELSE (* OperandSize = 16 *)
IF top 2 bytes of stack not within stack limits
THEN #SS(0); FI;
tempEIP := Pop();
tempEIP := tempEIP AND 0000FFFFH;
IF tempEIP not within code segment limits
THEN #GP(0); FI;
EIP := tempEIP;
IF ShadowStackEnabled(CPL)
tempSsEip = ShadowStackPop4B();
IF EIP != tempSsEIP
THEN #CP(NEAR_RET); FI;
FI;
FI;
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
RET—Return From Procedure
Vol. 2B
4-565
INSTRUCTION SET REFERENCE, M-U
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 64
THEN
RSP := RSP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
FI;
FI;
(* Real-address mode or virtual-8086 mode *)
IF ((PE = 0) or (PE = 1 AND VM = 1)) and instruction = far return
THEN
IF OperandSize = 32
THEN
IF top 8 bytes of stack not within stack limits
THEN #SS(0); FI;
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE (* OperandSize = 16 *)
IF top 4 bytes of stack not within stack limits
THEN #SS(0); FI;
tempEIP := Pop();
tempEIP := tempEIP AND 0000FFFFH;
IF tempEIP not within code segment limits
THEN #GP(0); FI;
EIP := tempEIP;
CS := Pop(); (* 16-bit pop *)
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
SP := SP + (SRC AND FFFFH);
FI;
FI;
(* Protected mode, not virtual-8086 mode *)
IF (PE = 1 and VM = 0 and IA32_EFER.LMA = 0) and instruction = far return
THEN
IF OperandSize = 32
THEN
IF second doubleword on stack is not within stack limits
THEN #SS(0); FI;
ELSE (* OperandSize = 16 *)
IF second word on stack is not within stack limits
THEN #SS(0); FI;
FI;
IF return code segment selector is NULL
THEN #GP(0); FI;
IF return code segment selector addresses descriptor beyond descriptor table limit
THEN #GP(selector); FI;
Obtain descriptor to which return code segment selector points from descriptor table;
4-566
Vol. 2B
RET—Return From Procedure
INSTRUCTION SET REFERENCE, M-U
IF return code segment descriptor is not a code segment
THEN #GP(selector); FI;
IF return code segment selector RPL < CPL
THEN #GP(selector); FI;
IF return code segment descriptor is conforming
and return code segment DPL > return code segment selector RPL
THEN #GP(selector); FI;
IF return code segment descriptor is non-conforming and return code
segment DPL ≠ return code segment selector RPL
THEN #GP(selector); FI;
IF return code segment descriptor is not present
THEN #NP(selector); FI:
IF return code segment selector RPL > CPL
THEN GOTO RETURN-TO-OUTER-PRIVILEGE-LEVEL;
ELSE GOTO RETURN-TO-SAME-PRIVILEGE-LEVEL;
FI;
FI;
RETURN-TO-SAME-PRIVILEGE-LEVEL:
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE (* OperandSize = 16 *)
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop *)
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
IF ShadowStackEnabled(CPL)
(* SSP must be 8 byte aligned *)
IF SSP AND 0x7 != 0
THEN #CP(FAR-RET/IRET); FI;
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
prevSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
(* do a 64 bit-compare to check if any bits beyond bit 15 are set *)
tempCS = CS; (* zero pad to 64 bit *)
IF tempCS != tempSsCS
THEN #CP(FAR-RET/IRET); FI;
(* do a 64 bit-compare; pad CSBASE+RIP with 0 for 32 bit LIP*)
IF CSBASE + RIP != tempSsLIP
THEN #CP(FAR-RET/IRET); FI;
RET—Return From Procedure
Vol. 2B
4-567
INSTRUCTION SET REFERENCE, M-U
(* prevSSP must be 4 byte aligned *)
IF prevSSP AND 0x3 != 0
THEN #CP(FAR-RET/IRET); FI;
(* In legacy mode SSP must be in low 4GB *)
IF prevSSP[63:32] != 0
THEN #GP(0); FI;
SSP := prevSSP
FI;
RETURN-TO-OUTER-PRIVILEGE-LEVEL:
IF top (16 + SRC) bytes of stack are not within stack limits (OperandSize = 32)
or top (8 + SRC) bytes of stack are not within stack limits (OperandSize = 16)
THEN #SS(0); FI;
Read return segment selector;
IF stack segment selector is NULL
THEN #GP(0); FI;
IF return stack segment selector index is not within its descriptor table limits
THEN #GP(selector); FI;
Read segment descriptor pointed to by return segment selector;
IF stack segment selector RPL ≠ RPL of the return code segment selector
or stack segment is not a writable data segment
or stack segment descriptor DPL ≠ RPL of the return code segment selector
THEN #GP(selector); FI;
IF stack segment not present
THEN #SS(StackSegmentSelector); FI;
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded; segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded; seg. descriptor loaded *)
ELSE (* OperandSize = 16 *)
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop; segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
4-568
Vol. 2B
RET—Return From Procedure
INSTRUCTION SET REFERENCE, M-U
SP := SP + SRC;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 16-bit pop; segment descriptor loaded *)
FI;
IF ShadowStackEnabled(CPL)
(* check if 8 byte aligned *)
IF SSP AND 0x7 != 0
THEN #CP(FAR-RET/IRET); FI;
IF ReturnCodeSegmentSelector(RPL) !=3
THEN
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
(* Do 64 bit compare to detect bits beyond 15 being set *)
tempCS = CS; (* zero extended to 64 bit *)
IF tempCS != tempSsCS
THEN #CP(FAR-RET/IRET); FI;
(* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LA *)
IF CSBASE + RIP != tempSsLIP
THEN #CP(FAR-RET/IRET); FI;
(* check if 4 byte aligned *)
IF tempSSP AND 0x3 != 0
THEN #CP(FAR-RET/IRET); FI;
FI;
FI;
tempOldCPL = CPL;
CPL := ReturnCodeSegmentSelector(RPL);
ESP := tempESP;
SS := tempSS;
tempOldSSP = SSP;
IF ShadowStackEnabled(CPL)
IF CPL = 3
THEN tempSSP := IA32_PL3_SSP; FI;
IF tempSSP[63:32] != 0
THEN #GP(0); FI;
SSP := tempSSP
FI;
(* Now past all faulting points; safe to free the token. The token free is done using the old SSP
* and using a supervisor override as old CPL was a supervisor privilege level *)
IF ShadowStackEnabled(tempOldCPL)
expected_token_value = tempOldSSP | BUSY_BIT (* busy bit - bit position 0 - must be set *)
new_token_value = tempOldSSP
(* clear the busy bit *)
shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)
FI;
FI;
FOR each SegReg in (ES, FS, GS, and DS)
DO
tempDesc := descriptor cache for SegReg (* hidden part of segment register *)
IF (SegmentSelector == NULL) OR (tempDesc(DPL) < CPL AND tempDesc(Type) is (data or non-conforming code)))
RET—Return From Procedure
Vol. 2B
4-569
INSTRUCTION SET REFERENCE, M-U
THEN (* Segment register invalid *)
SegmentSelector := 0; (*Segment selector becomes null*)
FI;
OD;
IF instruction has immediate operand
THEN (* Release parameters from calling procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE (* StackAddressSize = 16 *)
SP := SP + SRC;
FI;
FI;
(* IA-32e Mode *)
IF (PE = 1 and VM = 0 and IA32_EFER.LMA = 1) and instruction = far return
THEN
IF OperandSize = 32
THEN
IF second doubleword on stack is not within stack limits
THEN #SS(0); FI;
IF first or second doubleword on stack is not in canonical space
THEN #SS(0); FI;
ELSE
IF OperandSize = 16
THEN
IF second word on stack is not within stack limits
THEN #SS(0); FI;
IF first or second word on stack is not in canonical space
THEN #SS(0); FI;
ELSE (* OperandSize = 64 *)
IF first or second quadword on stack is not in canonical space
THEN #SS(0); FI;
FI
FI;
IF return code segment selector is NULL
THEN GP(0); FI;
IF return code segment selector addresses descriptor beyond descriptor table limit
THEN GP(selector); FI;
IF return code segment selector addresses descriptor in non-canonical space
THEN GP(selector); FI;
Obtain descriptor to which return code segment selector points from descriptor table;
IF return code segment descriptor is not a code segment
THEN #GP(selector); FI;
IF return code segment descriptor has L-bit = 1 and D-bit = 1
THEN #GP(selector); FI;
IF return code segment selector RPL < CPL
THEN #GP(selector); FI;
IF return code segment descriptor is conforming
and return code segment DPL > return code segment selector RPL
THEN #GP(selector); FI;
IF return code segment descriptor is non-conforming
and return code segment DPL ≠ return code segment selector RPL
4-570
Vol. 2B
RET—Return From Procedure
INSTRUCTION SET REFERENCE, M-U
THEN #GP(selector); FI;
IF return code segment descriptor is not present
THEN #NP(selector); FI:
IF return code segment selector RPL > CPL
THEN GOTO IA-32E-MODE-RETURN-TO-OUTER-PRIVILEGE-LEVEL;
ELSE GOTO IA-32E-MODE-RETURN-TO-SAME-PRIVILEGE-LEVEL;
FI;
FI;
IA-32E-MODE-RETURN-TO-SAME-PRIVILEGE-LEVEL:
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI;
IF the return instruction pointer is not within canonical address space
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded *)
ELSE
IF OperandSize = 16
THEN
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop *)
ELSE (* OperandSize = 64 *)
RIP := Pop();
CS := Pop(); (* 64-bit pop, high-order 48 bits discarded *)
FI;
FI;
IF instruction has immediate operand
THEN (* Release parameters from stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
IF ShadowStackEnabled(CPL)
IF SSP AND 0x7 != 0 (* check if aligned to 8 bytes *)
THEN #CP(FAR-RET/IRET); FI;
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
tempCS = CS; (* zero padded to 64 bit *)
IF tempCS != tempSsCS (* 64 bit compare; CS zero padded to 64 bits *)
THEN #CP(FAR-RET/IRET); FI;
IF CSBASE + RIP != tempSsLIP (* 64 bit compare *)
RET—Return From Procedure
Vol. 2B
4-571
INSTRUCTION SET REFERENCE, M-U
THEN #CP(FAR-RET/IRET); FI;
IF tempSSP AND 0x3 != 0 (* check if aligned to 4 bytes *)
THEN #CP(FAR-RET/IRET); FI;
IF (CS.L = 0 AND tempSSP[63:32] != 0) OR
(CS.L = 1 AND tempSSP is not canonical relative to the current paging mode)
THEN #GP(0); FI;
SSP := tempSSP
FI;
IA-32E-MODE-RETURN-TO-OUTER-PRIVILEGE-LEVEL:
IF top (16 + SRC) bytes of stack are not within stack limits (OperandSize = 32)
or top (8 + SRC) bytes of stack are not within stack limits (OperandSize = 16)
THEN #SS(0); FI;
IF top (16 + SRC) bytes of stack are not in canonical address space (OperandSize =32)
or top (8 + SRC) bytes of stack are not in canonical address space (OperandSize = 16)
or top (32 + SRC) bytes of stack are not in canonical address space (OperandSize = 64)
THEN #SS(0); FI;
Read return stack segment selector;
IF stack segment selector is NULL
THEN
IF new CS descriptor L-bit = 0
THEN #GP(selector);
IF stack segment selector RPL = 3
THEN #GP(selector);
FI;
IF return stack segment descriptor is not within descriptor table limits
THEN #GP(selector); FI;
IF return stack segment descriptor is in non-canonical address space
THEN #GP(selector); FI;
Read segment descriptor pointed to by return segment selector;
IF stack segment selector RPL ≠ RPL of the return code segment selector
or stack segment is not a writable data segment
or stack segment descriptor DPL ≠ RPL of the return code segment selector
THEN #GP(selector); FI;
IF stack segment not present
THEN #SS(StackSegmentSelector); FI;
IF the return instruction pointer is not within the return code segment limit
THEN #GP(0); FI:
IF the return instruction pointer is not within canonical address space
THEN #GP(0); FI;
IF OperandSize = 32
THEN
EIP := Pop();
CS := Pop(); (* 32-bit pop, high-order 16 bits discarded, segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
4-572
Vol. 2B
RET—Return From Procedure
INSTRUCTION SET REFERENCE, M-U
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 32-bit pop, high-order 16 bits discarded, segment descriptor loaded *)
ELSE
IF OperandSize = 16
THEN
EIP := Pop();
EIP := EIP AND 0000FFFFH;
CS := Pop(); (* 16-bit pop; segment descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
tempESP := Pop();
tempSS := Pop(); (* 16-bit pop; segment descriptor loaded *)
ELSE (* OperandSize = 64 *)
RIP := Pop();
CS := Pop(); (* 64-bit pop; high-order 48 bits discarded; seg. descriptor loaded *)
CS(RPL) := ReturnCodeSegmentSelector(RPL);
IF instruction has immediate operand
THEN (* Release parameters from called procedure’s stack *)
RSP := RSP + SRC;
FI;
tempESP := Pop();
tempSS := Pop(); (* 64-bit pop; high-order 48 bits discarded; seg. desc. loaded *)
FI;
FI;
IF ShadowStackEnabled(CPL)
(* check if 8 byte aligned *)
IF SSP AND 0x7 != 0
THEN #CP(FAR-RET/IRET); FI;
IF ReturnCodeSegmentSelector(RPL) !=3
THEN
tempSsCS = shadow_stack_load 8 bytes from SSP+16;
tempSsLIP = shadow_stack_load 8 bytes from SSP+8;
tempSSP = shadow_stack_load 8 bytes from SSP;
SSP = SSP + 24;
(* Do 64 bit compare to detect bits beyond 15 being set *)
RET—Return From Procedure
Vol. 2B
4-573
INSTRUCTION SET REFERENCE, M-U
tempCS = CS; (* zero padded to 64 bit *)
IF tempCS != tempSsCS
THEN #CP(FAR-RET/IRET); FI;
(* Do 64 bit compare; pad CSBASE+RIP with 0 for 32 bit LIP *)
IF CSBASE + RIP != tempSsLIP
THEN #CP(FAR-RET/IRET); FI;
(* check if 4 byte aligned *)
IF tempSSP AND 0x3 != 0
THEN #CP(FAR-RET/IRET); FI;
FI;
FI;
tempOldCPL = CPL;
CPL := ReturnCodeSegmentSelector(RPL);
ESP := tempESP;
SS := tempSS;
tempOldSSP = SSP;
IF ShadowStackEnabled(CPL)
IF CPL = 3
THEN tempSSP := IA32_PL3_SSP; FI;
IF (CS.L = 0 AND tempSSP[63:32] != 0) OR
(CS.L = 1 AND tempSSP is not canonical relative to the current paging mode)
THEN #GP(0); FI;
SSP := tempSSP
FI;
(* Now past all faulting points; safe to free the token. The token free is done using the old SSP
* and using a supervisor override as old CPL was a supervisor privilege level *)
IF ShadowStackEnabled(tempOldCPL)
expected_token_value = tempOldSSP | BUSY_BIT
(* busy bit - bit position 0 - must be set *)
new_token_value = tempOldSSP
(* clear the busy bit *)
shadow_stack_lock_cmpxchg8b(tempOldSSP, new_token_value, expected_token_value)
FI;
FOR each of segment register (ES, FS, GS, and DS)
DO
IF segment register points to data or non-conforming code segment
and CPL > segment descriptor DPL; (* DPL in hidden part of segment register *)
THEN SegmentSelector := 0; (* SegmentSelector invalid *)
FI;
OD;
IF instruction has immediate operand
THEN (* Release parameters from calling procedure’s stack *)
IF StackAddressSize = 32
THEN
ESP := ESP + SRC;
ELSE
IF StackAddressSize = 16
THEN
SP := SP + SRC;
ELSE (* StackAddressSize = 64 *)
RSP := RSP + SRC;
FI;
FI;
FI;
4-574
Vol. 2B
RET—Return From Procedure
INSTRUCTION SET REFERENCE, M-U
Flags Affected
None.
Protected Mode Exceptions
#GP(0)
If the return code or stack segment selector is NULL.
If the return instruction pointer is not within the return code segment limit.
If returning to 32-bit or compatibility mode and the previous SSP from shadow stack (when
returning to CPL <3) or from IA32_PL3_SSP (returning to CPL 3) is beyond 4GB.
#GP(selector)
If the RPL of the return code segment selector is less then the CPL.
If the return code or stack segment selector index is not within its descriptor table limits.
If the return code segment descriptor does not indicate a code segment.
If the return code segment is non-conforming and the segment selector’s DPL is not equal to
the RPL of the code segment’s segment selector
If the return code segment is conforming and the segment selector’s DPL greater than the RPL
of the code segment’s segment selector
If the stack segment is not a writable data segment.
If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
If the stack segment descriptor DPL is not equal to the RPL of the return code segment
selector.
#SS(0)
If the top bytes of stack are not within stack limits.
If the return stack segment is not present.
#NP(selector)
If the return code segment is not present.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If an unaligned memory access occurs when the CPL is 3 and alignment checking is enabled.
#CP(Far-RET/IRET) If the previous SSP from shadow stack (when returning to CPL <3) or from IA32_PL3_SSP
(returning to CPL 3) is not 4 byte aligned.
If return instruction pointer from stack and shadow stack do not match.
Real-Address Mode Exceptions
#GP
If the return instruction pointer is not within the return code segment limit
#SS
If the top bytes of stack are not within stack limits.
Virtual-8086 Mode Exceptions
#GP(0)
If the return instruction pointer is not within the return code segment limit
#SS(0)
If the top bytes of stack are not within stack limits.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If an unaligned memory access occurs when alignment checking is enabled.
Compatibility Mode Exceptions
Same as 64-bit mode exceptions.
RET—Return From Procedure
Vol. 2B
4-575
INSTRUCTION SET REFERENCE, M-U
64-Bit Mode Exceptions
#GP(0)
If the return instruction pointer is non-canonical.
If the return instruction pointer is not within the return code segment limit.
If the stack segment selector is NULL going back to compatibility mode.
If the stack segment selector is NULL going back to CPL3 64-bit mode.
If a NULL stack segment selector RPL is not equal to CPL going back to non-CPL3 64-bit mode.
If the return code segment selector is NULL.
If returning to 32-bit or compatibility mode and the previous SSP from shadow stack (when
returning to CPL <3) or from IA32_PL3_SSP (returning to CPL 3) is beyond 4GB.
#GP(selector)
If the proposed segment descriptor for a code segment does not indicate it is a code segment.
If the proposed new code segment descriptor has both the D-bit and L-bit set.
If the DPL for a nonconforming-code segment is not equal to the RPL of the code segment
selector.
If CPL is greater than the RPL of the code segment selector.
If the DPL of a conforming-code segment is greater than the return code segment selector
RPL.
If a segment selector index is outside its descriptor table limits.
If a segment descriptor memory address is non-canonical.
If the stack segment is not a writable data segment.
If the stack segment descriptor DPL is not equal to the RPL of the return code segment
selector.
If the stack segment selector RPL is not equal to the RPL of the return code segment selector.
#SS(0)
If an attempt to pop a value off the stack violates the SS limit.
If an attempt to pop a value off the stack causes a non-canonical address to be referenced.
#NP(selector)
If the return code or stack segment is not present.
#PF(fault-code)
If a page fault occurs.
#AC(0)
If alignment checking is enabled and an unaligned memory reference is made while the
current privilege level is 3.
#CP(Far-RET/IRET) If the previous SSP from shadow stack (when returning to CPL <3) or from IA32_PL3_SSP
(returning to CPL 3) is not 4 byte aligned.
If return instruction pointer from stack and shadow stack do not match.
4-576
Vol. 2B
RET—Return From Procedure
|
||
|
|
|