111 lines
12 KiB
Markdown
Executable File
111 lines
12 KiB
Markdown
Executable File
# SAL/SAR/SHL/SHR — Shift
|
||
|
||
## Description
|
||
|
||
Shifts the bits in the first operand (destination operand) to the left or right by the number of bits specified in the second operand (count
|
||
operand). Bits shifted beyond the destination operand boundary are first shifted into the CF flag, then discarded. At the end of the shift
|
||
operation, the CF flag contains the last bit shifted out of the destination operand.
|
||
|
||
## Instruction
|
||
|
||
| Opcode | Assembly | Op/En | Modern Mode | Legacy Mode | Description |
|
||
|------------------|------------------|-------|-------------|-------------|--------------------------------------------------------------------|
|
||
| D0 /4 | SAL r/m8, 1 | M1 | Valid | Valid | Multiply r/m8 by 2, once. |
|
||
| REX + D0 /4 | SAL r/m8**, 1 | M1 | Valid | N.E. | Multiply r/m8 by 2, once. |
|
||
| D2 /4 | SAL r/m8, CL | MC | Valid | Valid | Multiply r/m8 by 2, CL times. |
|
||
| REX + D2 /4 | SAL r/m8**, CL | MC | Valid | N.E. | Multiply r/m8 by 2, CL times. |
|
||
| C0 /4 ib | SAL r/m8, imm8 | MI | Valid | Valid | Multiply r/m8 by 2, imm8 times. |
|
||
| REX + C0 /4 ib | SAL r/m8**, imm8 | MI | Valid | N.E. | Multiply r/m8 by 2, imm8 times. |
|
||
| D1 /4 | SAL r/m16, 1 | M1 | Valid | Valid | Multiply r/m16 by 2, once. |
|
||
| D3 /4 | SAL r/m16, CL | MC | Valid | Valid | Multiply r/m16 by 2, CL times. |
|
||
| C1 /4 ib | SAL r/m16, imm8 | MI | Valid | Valid | Multiply r/m16 by 2, imm8 times. |
|
||
| D1 /4 | SAL r/m32, 1 | M1 | Valid | Valid | Multiply r/m32 by 2, once. |
|
||
| REX.W + D1 /4 | SAL r/m64, 1 | M1 | Valid | N.E. | Multiply r/m64 by 2, once. |
|
||
| D3 /4 | SAL r/m32, CL | MC | Valid | Valid | Multiply r/m32 by 2, CL times. |
|
||
| REX.W + D3 /4 | SAL r/m64, CL | MC | Valid | N.E. | Multiply r/m64 by 2, CL times. |
|
||
| C1 /4 ib | SAL r/m32, imm8 | MI | Valid | Valid | Multiply r/m32 by 2, imm8 times. |
|
||
| REX.W + C1 /4 ib | SAL r/m64, imm8 | MI | Valid | N.E. | Multiply r/m64 by 2, imm8 times. |
|
||
| D0 /7 | SAR r/m8, 1 | M1 | Valid | Valid | Signed divide* r/m8 by 2, once. |
|
||
| REX + D0 /7 | SAR r/m8**, 1 | M1 | Valid | N.E. | Signed divide* r/m8 by 2, once. |
|
||
| D2 /7 | SAR r/m8, CL | MC | Valid | Valid | Signed divide* r/m8 by 2, CL times. |
|
||
| REX + D2 /7 | SAR r/m8**, CL | MC | Valid | N.E. | Signed divide* r/m8 by 2, CL times. |
|
||
| C0 /7 ib | SAR r/m8, imm8 | MI | Valid | Valid | Signed divide* r/m8 by 2, imm8 time. |
|
||
| REX + C0 /7 ib | SAR r/m8**, imm8 | MI | Valid | N.E. | Signed divide* r/m8 by 2, imm8 times. |
|
||
| D1 /7 | SAR r/m16,1 | M1 | Valid | Valid | Signed divide* r/m16 by 2, once. |
|
||
| D3 /7 | SAR r/m16, CL | MC | Valid | Valid | Signed divide* r/m16 by 2, CL times. |
|
||
| C1 /7 ib | SAR r/m16, imm8 | MI | Valid | Valid | Signed divide* r/m16 by 2, imm8 times. |
|
||
| D1 /7 | SAR r/m32, 1 | M1 | Valid | Valid | Signed divide* r/m32 by 2, once. |
|
||
| REX.W + D1 /7 | SAR r/m64, 1 | M1 | Valid | N.E. | Signed divide* r/m64 by 2, once. |
|
||
| D3 /7 | SAR r/m32, CL | MC | Valid | Valid | Signed divide* r/m32 by 2, CL times. |
|
||
| REX.W + D3 /7 | SAR r/m64, CL | MC | Valid | N.E. | Signed divide* r/m64 by 2, CL times. |
|
||
| C1 /7 ib | SAR r/m32, imm8 | MI | Valid | Valid | Signed divide* r/m32 by 2, imm8 times. |
|
||
| REX.W + C1 /7 ib | SAR r/m64, imm8 | MI | Valid | N.E. | Signed divide* r/m64 by 2, imm8 times |
|
||
| D0 /4 | SHL r/m8, 1 | M1 | Valid | Valid | Multiply r/m8 by 2, once. |
|
||
| REX + D0 /4 | SHL r/m8**, 1 | M1 | Valid | N.E. | Multiply r/m8 by 2, once. |
|
||
| D2 /4 | SHL r/m8, CL | MC | Valid | Valid | Multiply r/m8 by 2, CL times. |
|
||
| REX + D2 /4 | SHL r/m8**, CL | MC | Valid | N.E. | Multiply r/m8 by 2, CL times. |
|
||
| C0 /4 ib | SHL r/m8, imm8 | MI | Valid | Valid | Multiply r/m8 by 2, imm8 times. |
|
||
| REX + C0 /4 ib | SHL r/m8**, imm8 | MI | Valid | N.E. | Multiply r/m8 by 2, imm8 times. |
|
||
| D1 /4 | SHL r/m16,1 | M1 | Valid | Valid | Multiply r/m16 by 2, once. |
|
||
| D3 /4 | SHL r/m16, CL | MC | Valid | Valid | Multiply r/m16 by 2, CL times. |
|
||
| C1 /4 ib | SHL r/m16, imm8 | MI | Valid | Valid | Multiply r/m16 by 2, imm8 times. |
|
||
| D1 /4 | SHL r/m32,1 | M1 | Valid | Valid | Multiply r/m32 by 2, once. |
|
||
| REX.W + D1 /4 | SHL r/m64,1 | M1 | Valid | N.E. | Multiply r/m64 by 2, once. |
|
||
| D3 /4 | SHL r/m32, CL | MC | Valid | Valid | Multiply r/m32 by 2, CL times. |
|
||
| REX.W + D3 /4 | SHL r/m64, CL | MC | Valid | N.E. | Multiply r/m64 by 2, CL times. |
|
||
| C1 /4 ib | SHL r/m32, imm8 | MI | Valid | Valid | Multiply r/m32 by 2, imm8 times. |
|
||
| REX.W + C1 /4 ib | SHL r/m64, imm8 | MI | Valid | N.E. | Multiply r/m64 by 2, imm8 times. |
|
||
| D0 /5 | SHR r/m8,1 | M1 | Valid | Valid | Unsigned divide r/m8 by 2, once. |
|
||
| REX + D0 /5 | SHR r/m8**, 1 | M1 | Valid | N.E. | Unsigned divide r/m8 by 2, once. |
|
||
| D2 /5 | SHR r/m8, CL | MC | Valid | Valid | Unsigned divide r/m8 by 2, CL times. |
|
||
| REX + D2 /5 | SHR r/m8**, CL | MC | Valid | N.E. | Unsigned divide r/m8 by 2, CL times. |
|
||
| C0 /5 ib | SHR r/m8, imm8 | MI | Valid | Valid | Unsigned divide r/m8 by 2, imm8 times. |
|
||
| REX + C0 /5 ib | SHR r/m8**, imm8 | MI | Valid | N.E. | Unsigned divide r/m8 by 2, imm8 times. |
|
||
| D1 /5 | SHR r/m16, 1 | M1 | Valid | Valid | Unsigned divide r/m16 by 2, once. |
|
||
| D3 /5 | SHR r/m16, CL | MC | Valid | Valid | Unsigned divide r/m16 by 2, CL times |
|
||
| C1 /5 ib | SHR r/m16, imm8 | MI | Valid | Valid | Unsigned divide r/m16 by 2, imm8 times. |
|
||
| D1 /5 | SHR r/m32, 1 | M1 | Valid | Valid | Unsigned divide r/m32 by 2, once. |
|
||
| REX.W + D1 /5 | SHR r/m64, 1 | M1 | Valid | N.E. | Unsigned divide r/m64 by 2, once. |
|
||
| D3 /5 | SHR r/m32, CL | MC | Valid | Valid | Unsigned divide r/m32 by 2, CL times. |
|
||
| REX.W + D3 /5 | SHR r/m64, CL | MC | Valid | N.E. | Unsigned divide r/m64 by 2, CL times. |
|
||
| C1 /5 ib | SHR r/m32, imm8 | MI | Valid | Valid | Unsigned divide r/m32 by 2, imm8 times. |
|
||
| REX.W + C1 /5 ib | SHR r/m64, imm8 | MI | Valid | N.E. | Unsigned divide r/m64 by 2, imm8 times. |
|
||
|
||
- 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.
|
||
|
||
- Not the same form of division as IDIV; rounding is toward negative infinity.
|
||
|
||
## Information
|
||
|
||
The destination operand can be a register or a memory location. The count operand can be an immediate value or the CL register. The count is
|
||
masked to 5 bits (or 6 bits if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if 64-bit mode and REX.W is
|
||
used). A special opcode encoding is provided for a count of 1.
|
||
|
||
The shift arithmetic left (SAL) and shift logical left (SHL) instructions perform the same operation; they shift the bits in the destination
|
||
operand to the left (toward more significant bit locations). For each shift count, the most significant bit of the destination operand is
|
||
shifted into the CF flag, and the least significant bit is cleared.
|
||
|
||
The shift arithmetic right (SAR) and shift logical right (SHR) instructions shift the bits of the destination operand to the right (toward less
|
||
significant bit locations). For each shift count, the least significant bit of the destination operand is shifted into the CF flag, and the
|
||
most significant bit is either set or cleared depending on the instruction type. The SHR instruction clears the most significant bit (see
|
||
Figure 7-8 in the Intel® 64 and IA-32 Architectures Software Developer’s Manual, Volume 1); the SAR instruction sets or clears the most
|
||
significant bit to correspond to the sign (most significant bit) of the original value in the destination operand. In effect, the SAR
|
||
instruction fills the empty bit position’s shifted value with the sign of the unshifted value.
|
||
|
||
The SAR and SHR instructions can be used to perform signed or unsigned division, respectively, of the destination operand by powers of 2. For
|
||
example, using the SAR instruction to shift a signed integer 1 bit to the right divides the value by 2.
|
||
|
||
Using the SAR instruction to perform a division operation does not produce the same result as the IDIV instruction. The quotient from the IDIV
|
||
instruction is rounded toward zero, whereas the “quotient” of the SAR instruction is rounded toward negative infinity. This difference is
|
||
apparent only for negative numbers. For example, when the IDIV instruction is used to divide -9 by 4, the result is -2 with a remainder of -1.
|
||
If the SAR instruction is used to shift -9 right by two bits, the result is -3 and the “remainder” is +3; however, the SAR instruction stores
|
||
only the most significant bit of the remainder (in the CF flag).
|
||
|
||
The OF flag is affected only on 1-bit shifts. For left shifts, the OF flag is set to 0 if the most-significant bit of the result is the same as
|
||
the CF flag (that is, the top two bits of the original operand were the same); otherwise, it is set to 1. For the SAR instruction, the OF flag
|
||
is cleared for all 1-bit shifts. For the SHR instruction, the OF flag is set to the most-significant bit of the original operand.
|
||
|
||
In 64-bit mode, the instruction’s default operation size is 32 bits and the mask width for CL is 5 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 and sets the mask
|
||
width for CL to 6 bits. See the summary chart at the beginning of this section for encoding data and limits.
|