 Logical Instructions Rotate Instruction 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) Yes Yes Yes Yes Yes NO 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 = .bv { width:15px; } 00000011 ``` ``` Finally AL = 6 = .bv { width:15px; } 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 .bv { width:15px; } 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