SHRD

Double Precision Shift Right

Opcodes

Hex Mnemonic Encoding Long Mode Legacy Mode Description
REX.W + 0F AD SHRD r/m64, r64, CL B Valid N.E. Shift r/m64 to right CL places while shifting bits from r64 in from the left.
0F AD SHRD r/m32, r32, CL B Valid Valid Shift r/m32 to right CL places while shifting bits from r32 in from the left.
REX.W + 0F AC SHRD r/m64, r64, imm8 A Valid N.E. Shift r/m64 to right imm8 places while shifting bits from r64 in from the left.
0F AC SHRD r/m32, r32, imm8 A Valid Valid Shift r/m32 to right imm8 places while shifting bits from r32 in from the left.
0F AD SHRD r/m16, r16, CL B Valid Valid Shift r/m16 to right CL places while shifting bits from r16 in from the left.
0F AC SHRD r/m16, r16, imm8 A Valid Valid Shift r/m16 to right imm8 places while shifting bits from r16 in from the left.

Instruction Operand Encoding

Op/En Operand 0 Operand 1 Operand 2 Operand 3
A NA imm8 ModRM:reg (r) ModRM:r/m (w)
B NA CL ModRM:reg (r) ModRM:r/m (w)

Description

The SHRD instruction is useful for multi-precision shifts of 64 bits or more.

The instruction shifts the first operand (destination operand) to the right the number of bits specified by the third operand (count operand). The second operand (source operand) provides bits to shift in from the left (starting with the most significant bit of the destination operand).

The destination operand can be a register or a memory location; the source operand is a register. The count operand is an unsigned integer that can be stored in an immediate byte or the CL register. If the count operand is CL, the shift count is the logical AND of CL and a count mask. In non-64-bit modes and default 64-bit mode, the width of the count mask is 5 bits. Only bits 0 through 4 of the count register are used (masking the count to a value between 0 and 31). If the count is greater than the operand size, the result is undefined.

If the count is 1 or greater, the CF flag is filled with the last bit shifted out of the destination operand. For a 1-bit shift, the OF flag is set if a sign change occurred; otherwise, it is cleared. If the count operand is 0, flags are not affected.

In 64-bit mode, the instruction's default operation size is 32 bits. Using a REX prefix in the form of REX.R permits access to additional registers (R8-R15). Using a REX prefix in the form of REX.W promotes operation to 64 bits (upgrading the count mask to 6 bits). See the summary chart at the beginning of this section for encoding data and limits.

Pseudo Code

IF (In 64-Bit Mode and REX.W = 1)
	COUNT = COUNT MOD 64;
ELSE
	COUNT = COUNT MOD 32;
FI SIZE = OperandSize;
IF COUNT = 0
	No operation;
ELSE
	IF COUNT > SIZE
		(* Bad parameters *)
		DEST is undefined;
		CF, OF, SF, ZF, AF, PF are undefined;
	ELSE
		(* Perform the shift *)
		CF = BIT[DEST, COUNT - 1]; (* Last bit shifted out on exit *)
		FOR i = 0 TO SIZE - 1 - COUNT
			DO BIT[DEST, i] = BIT[DEST, i + COUNT];
			FOR i = SIZE - COUNT TO SIZE - 1 DO BIT[DEST, i] = BIT[SRC, i + COUNT - SIZE];
	FI;
FI;

Flags Affected

If the count is 1 or greater, the CF flag is filled with the last bit shifted out of the destination operand and the SF, ZF, and PF flags are set according to the value of the result. For a 1-bit shift, the OF flag is set if a sign change occurred; otherwise, it is cleared. For shifts greater than 1 bit, the OF flag is undefined. If a shift occurs, the AF flag is undefined. If the count operand is 0, the flags are not affected. If the count is greater than the operand size, the flags are undefined.

Exceptions

64-Bit Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#PF(fault-code) If a page fault occurs.
#GP(0) If the memory address is in a non-canonical form.
#SS(0) If a memory address referencing the SS segment is in a non-canonical form.

Compatibility Mode Exceptions

Same exceptions as in protected mode.

Virtual-8086 Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made.
#PF(fault-code) If a page fault occurs.
#SS(0) If a memory operand effective address is outside the SS segment limit.
#GP(0) If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.

Real-Address Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#SS If a memory operand effective address is outside the SS segment limit.
#GP If a memory operand effective address is outside the CS, DS, ES, FS, or GS segment limit.

Protected Mode Exceptions

Exception Description
#UD If the LOCK prefix is used.
#AC(0) If alignment checking is enabled and an unaligned memory reference is made while the current privilege level is 3.
#PF(fault-code) If a page fault occurs.
#SS(0) If a memory operand effective address is outside the SS segment limit.
#GP(0) If the destination 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.