shl
Shift Logical Left
Shifts bits left (same as SAL).
Details
Shifts the bits of the destination operand left by the count specified in the immediate operand, filling vacated bits with zeros; leftmost bit is shifted into CF. Sets CF and OF based on shift; ZF, SF, PF reflect the result. Available in 8/16/32/64-bit variants; count is typically 1 or specified by imm8.
Pseudocode Operation
if (count == 0) return;
temp ← dest;
CF ← (dest >> (operand_size * 8 - count)) & 1;
result ← dest << count;
OF ← (result & sign_bit) != (temp & sign_bit);
ZF ← (result == 0);
SF ← (result & sign_bit) != 0;
PF ← popcount(result & 0xFF) % 2 == 0;
dest ← result;
Example
Encoding
Operands
-
dest
Register or memory operand -
src
8-bit signed immediate
Reference (Intel® SDM)
Instruction Forms
| Opcode | Instruction | Op/En | 64/32-bit Mode | CPUID | Description |
|---|---|---|---|---|---|
| D0 /4 | SAL r/m8, 1 | M1 | Valid Valid | Multiply r/m8 by 2, once. | |
| D2 /4 | SAL r/m8, CL | MC | Valid Valid | Multiply r/m8 by 2, CL times. | |
| C0 /4 ib | SAL r/m8, imm8 | MI | Valid Valid | 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 divide3 r/m8 by 2, once. | |
| D2 /7 | SAR r/m8, CL | MC | Valid Valid | Signed divide3 r/m8 by 2, CL times. | |
| C0 /7 ib | SAR r/m8, imm8 | MI | Valid Valid | Signed divide3 r/m8 by 2, imm8 times. | |
| D1 /7 | SAR r/m16,1 | M1 | Valid Valid | Signed divide3 r/m16 by 2, once. | |
| D3 /7 | SAR r/m16, CL | MC | Valid Valid | Signed divide3 r/m16 by 2, CL times. | |
| C1 /7 ib | SAR r/m16, imm8 | MI | Valid Valid | Signed divide3 r/m16 by 2, imm8 times. | |
| D1 /7 | SAR r/m32, 1 | M1 | Valid Valid | Signed divide3 r/m32 by 2, once. | |
| REX.W + D1 /7 | SAR r/m64, 1 | M1 | Valid N.E. | Signed divide3 r/m64 by 2, once. | |
| D3 /7 | SAR r/m32, CL | MC | Valid Valid | Signed divide3 r/m32 by 2, CL times. | |
| REX.W + D3 /7 | SAR r/m64, CL | MC | Valid N.E. | Signed divide3 r/m64 by 2, CL times. | |
| C1 /7 ib | SAR r/m32, imm8 | MI | Valid Valid | Signed divide3 r/m32 by 2, imm8 times. | |
| REX.W + C1 /7 ib | SAR r/m64, imm8 | MI | Valid N.E. | Signed divide3 r/m64 by 2, imm8 times | |
| D0 /4 | SHL r/m8, 1 | M1 | Valid Valid | Multiply r/m8 by 2, once. | |
| D2 /4 | SHL r/m8, CL | MC | Valid Valid | Multiply r/m8 by 2, CL times. | |
| C0 /4 ib | SHL r/m8, imm8 | MI | Valid Valid | 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. | |
| D2 /5 | SHR r/m8, CL | MC | Valid Valid | 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. | |
| D1 /5 | SHR r/m16, 1 | M1 | Valid Valid | Unsigned divide r/m16 by 2, once. SAL/SAR/SHL/SHR—Shift Vol. 2B 4-603 Opcode1 Instruction Op/ 64-Bit Compat/ Description En Mode Leg Mode | |
| 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. |
Description
Operation
IF OperandSize = 64 THEN countMASK := 3FH; ELSE countMASK := 1FH; FI tempCOUNT := (COUNT AND countMASK); origDEST := DEST; tempDEST := DEST; WHILE (tempCOUNT ≠ 0) DO IF instruction is SAL or SHL THEN CF := MSB(tempDEST); ELSE (* Instruction is SAR or SHR *) CF := LSB(tempDEST); FI; IF instruction is SAL or SHL THEN tempDEST := tempDEST ∗ 2; ELSE IF instruction is SAR THEN tempDEST := tempDEST / 2; (* Signed divide, rounding toward negative infinity *) ELSE (* Instruction is SHR *) tempDEST := tempDEST / 2 ; (* Unsigned divide *) FI; FI; tempCOUNT := tempCOUNT – 1; OD; (* Determine overflow for the various instructions *) IF (COUNT and countMASK) = 1 THEN IF instruction is SAL or SHL SAL/SAR/SHL/SHR—Shift Vol. 2B 4-605 THEN OF := MSB(tempDEST) XOR CF; ELSE IF instruction is SAR THEN OF := 0; ELSE (* Instruction is SHR *) OF := MSB(origDEST); FI; FI; ELSE IF (COUNT AND countMASK) = 0 THEN All flags unchanged; ELSE (* COUNT not 1 or 0 *) OF := undefined; FI; FI; DEST := tempDEST;
Flags Affected
The CF flag contains the value of the last bit shifted out of the destination operand; it is undefined for SHL and SHR instructions where the count is greater than or equal to the size (in bits) of the destination operand. The OF flag is affected only for 1-bit shifts (see “Description” above); otherwise, it is undefined. The SF, ZF, and PF flags are set according to the result. If the count is 0, the flags are not affected. For a non-zero count, the AF flag is undefined.