Shift Instructions 

Types of Shift Instructions

There are three types of shift instructions

 Logical shift instructions
SHL (SHift Left)
SHR (SHift Right)

Another interpretation:
Logical shift instructions work on unsigned binary numbers

 Arithmetic shift instructions
SAL (Shift Arithmetic Left)
SAR (Shift Arithmetic Right)

Another interpretation:
Arithmetic shift instructions work on signed binary numbers

 Double Precision Shift instructions
SHLD (Double Precision Shift Left)
SHRD (Double Precision Shift Right)

General syntax format

There are two different formats for logical and arithmetic shift instructions:

SHL/SHR/SAL/SAR r/m,  count
SHL/SHR/SAL/SAR r/m,  CL

count is an immediate value between 0 and 31. If a greater value is specified, Pentium takes only the least significant 5 bits as the count value (MODULUS 32).

Second format specifies count indirectly through CL

Only CL register can be used.
CL contents are not changed.
Useful if count value is known only at the run time as opposed at assembly time.

EFFECT of SHIFT INSTRUCTIONS on FLAGS

All shift instructions affect some flags like other instructions. However, the way Carry Flag (CF) and Overflow Flag (OF) affected are different.

Carry Flag (CF)Overflow Flag (OF)Zero Flag (ZF)Sign Flag (SF)Parity Flag(PF)Auxiliary Flag (AF)
YesYesYesYesYesNO

Auxiliary flag (AF): undefined.
Zero flag (ZF), Sign flag (SF) and parity flag (PF)are updated to reflect the result.
Carry flag (CF): Contains the last bit shifted out
Overflow flag (OF)
For multibit shifts : Undefined
For single bit shifts: OF is set if the leftmost bit has changed as a result of the shift, otherwise cleared.

Logical Shift Left Instruction (SHL)

Semantic:

SHL shifts the leftmost bit into the Carry Flag (CF) and overwrites the current value of the Carry Flag.
Each of the remaining bits is shifted leftwise and 0 is shifted into the rightmost bit.
Fig. m07540.1 The SHL AL, 2 instruction

Example: Shifting AL=3 leftwise by 1 bit
 mov AL, 3
 shl AL, 1	; shift left AL 1 place
 
S O L U T I O N
Initially AL = 3 =
00000011
Finally AL = 6 =
00000110
CF = 0
SF = 0
ZF = 0 because the result is not equal to 0.
PF = 1 because there are 2 bits 1 in AL.
OF = 0 Why?
 

Shifting left a Destination operand by N bits multiplies it by 2N. (signed and unsigned)

Example: Shifting BL=3Fh leftwise by 3 bits
 mov BL, 3Fh
 shl BL, 3	;shift left BL by 3 bit
 
S O L U T I O N
BL = F8h=248
11111000
CF = 1
SF = 1
ZF = 0 because the result is not equal to 0.
PF = 0 because there are odd numbers of bit 1 in BL.
OF is undefined
 

Example: Shifting leftwise AL by CL bit
 mov AX, 8F23h	; now AX=36643 (unsigned) or -28893 (signed)
 mov CX, 1
 shl AX, CL		; shift left AX 1 place
 
S O L U T I O N
AX = 1E46h= 7750
CF = 1
SF = 0
ZF = 0
PF = 0 because there are 3 bits 1 in AL.
OF = 1 because the leftmost bit of AX has changed from 1 to 0.
 

Unsigned Multiplication by a non-multiple of 2 can be achieved by a combination of SHL, MOV, ADD, or SUB instructions. Such multiplications are usually more efficient than multiplications using the MUL (Multiplication) instruction.

Example: Multiply AX by 19
 ; 19 = 16 + 2 + 1
 push	BX
 mov	BX , AX
 shl	BX , 1		; BX := AX*2
 add	BX , AX		; BX := AX * 3
 shl	AX , 4		; AX := AX * 16
 add	AX , BX		; AX := AX * 19
 pop	BX
 

Example: Multiply AX by 15
 ; 15 = 16 - 1
 push	BX
 mov	BX , AX
 shl	AX , 4		; AX := AX*16
 sub	AX , BX		; AX := 16*AX - AX
 pop	BX
 

Due to the possibility of having discarded bits that may yield incorect result, however, the usage of shift instructions for unsigned multiplication must be examined carefully.

Example: Multiply AX by 15 Accurately
 ; The trick is to use 32-bit register
 push	EBX
 movzx	EAX , AX	; extend AX into EAX
 mov	EBX , EAX
 shl	EAX , 4		; EAX := EAX*16
 sub	EAX , EBX	; EAX := 16*EAX - EAX
 pop	EBX
 

For multibit left-shifts the Carry Flag (CF) may not accurately reflect whether or not an unsigned out-of-range condition has occurred.

Example
 mov	BL , 80H	; BL := 10000000b
 shl	BL , 2
 

The result 00000000B in BL is incorrect although the Carry Flag (CF) is cleared.

Logical Shift Right Instruction (SHR)

SHR shifts the rightmost bit of operand into the Carry Flag; the current value of the Carry Flag is lost. Each of the remaining bits is shifted rightwise and 0 is shifted into the leftmost bit of operand.

SHR does not preserve the sign of a negative operand. Thus, SHR cannot be used to perform division on negative numbers.

Fig. m07540.2 The SHR AL, 3 instruction

Shifting right a Destination operand by N bits divides it by 2N (only unsigned).
If the value of the Destination is odd, the division is approximate.

Example
 mov	BL , 00000101B	; BL := 5
 shr	BL , 1		; BL := 2
 

Shift arithmetic Left (SAL)

SHL is equivalent to SAL.

Shift arithmetic Right (SAR)

SAR shifts the rightmost bit of operand into the Carry Flag; the current value of the Carry Flag is lost. Each of the remaining bits is shifted rightwise and, in addition, the leftmost bit is shifted into itself.

Fig. m07540.3 The SAR AL,4 instruction

Double Precision Shift Instructions

 The format of Double Shift instructions
SHLD/SHRD r/m16, r16, imm8
SHLD/SHRD r/m32, r32, imm8
SHLD/SHRD r/m16, r16, CL
SHLD/SHRD r/m32, r32, CL

All double precision shift instructions DO NOT MODIFY the second operand. The second operand only feeds their bits to the first operand.

Fig. m07540.4 The SHLD AX, BX, 2 Instruction
Fig. m07540.5 The SHRD AX, BX, 2 Instruction