6. Shifting Instructions
Shifting means to move bits right and left inside an
operand.
There are two ways to shift an operand’s bits:
1.Logical Shift 2.Arithmetic Shift
fills the newly created bit
position with zero
The newly created bit
position is filled with a copy
of the original number’s sign
bit
8. SHL (shift left) instruction
1. Performs a logical left shift on the destination operand
2. Filling the lowest bit with 0.
3. The highest bit is moved to the Carry flag
The bit that was in the Carry flag is discarded
CF
0
SHL destination, count
Shift
Count
9. SHL (shift left) instruction
The following lists the types of operands permitted by this
instruction:
SHL reg, imm8
SHL mem, imm8
SHL reg, cl
SHL mem, cl
integer between
0 and 255
CL register
can contain a shift
count
10. SHR (shift right) instruction
1. Performs a logical right shift on the destination
operand
2. Replacing the highest bit with a 0.
3. The lowest bit is copied into the Carry flag
The bit that was previously in the Carry flag is lost
Shift
Count
CF
0
SHR destination, count
13. Fast Multiplication
SHL can perform multiplication by powers of 2.
Shifting an unsigned integer left by n bits multiplies the
operand by 2n
For example, shifting 5 left by 1 bit produces 10
5 * 21 = 10
SHL dest, cnt
dest *= 2 cnt
mov dl, 5
Shl dl, 1
0 0 0 0 0 1 0 1 5
0 0 0 0 1 0 1 0 10
14. Fast Division
SHR can perform division by powers of 2.
Shifting an unsigned integer right by n bits divides the
operand by 2n
For example, shifting the 32 left by 1 bit produces 16
64 / 23 = 8
mov dl, 64
Shr dl, 3
0 1 0 0 0 0 0 0 64
0 0 0 0 1 0 0 0 8
SHR dest, cnt
dest /= 2 cnt
16. SAL & SAR
SAL (shift arithmetic left) instruction
Works the same as the SHL instruction, the lowest bit is
assigned to 0.
SAR (shift arithmetic right) instruction
Works the same as SHR but it preserves the number’s
sign bit
CF
0
17. Exercises (AL = ? & CF = ?)
17
mov al, -26
SAR al, 1
Mov CL, 1
Mov AL, 42
SAL AL, CL
SAR AL, BL
; AL = 11100110
; AL = 11110011 = (-13)10, CF=0
; To use CL as shift count
; AL = 00101010
; AL = 01010100 = (84)10, CF=0
;Error: only CL can be
used as count
18. Fast Signed Multiplication & Division
SAL/SAR can also be used in multiplication/division by 2n
with signed numbers
20. Rotate Inst.
Rotate instructions are the same as logical shift
instructions except that the lost bit from one end in
shifting is inserted in the other end in rotating.
They are circular shift or simply rotation.
21. ROL (Rotate Left) Instruction
1. Shifts each bit to the left.
2. The highest bit is copied into the Carry flag and the
lowest bit position.
Bit rotation does not lose bits. A bit rotated off one end
of a number appears again at the other end
ROL dest, cnt
22. ROR (Rotate Right) Instruction
Shifts each bit to the right.
The lowest bit is copied into the Carry flag and the
highest bit position.
ROR dest, cnt
23. Exercise
23
mov al, 128
rol al, 1
mov al, 00010000b
Rol al, 3
mov al, 01h
Ror al, 1
mov al, 00000100b
Ror al, 3
; AL = 10000000b , CF = 0
; AL = 00000001b = (1)10, CF=1
; AL = 10000000b, CF = 0
; AL = 00000001b
; AL = 10000000b , CF=1
; AL = 10000000b, CF = 1
24. RCL & RCR Instruction
There is another set of rotation instructions which are
RCL (rotate carry left) and RCR (rotate carry right).
They assume the carry bit is an extra bit in the operand
and rotate the whole bits including the carry bit.
RCL dest, cnt
RCR dest, cnt
25. Exercise
RCL = From LEFT to CF and from CF to RIGHT
RCR = From Right to CF and from CF to Left
RC? = From ? To CF and From CF to ?-1
clc
mov bl, 88h
rcl bl, 1
rcl bl, 1
; clear carry instruction, CF = 0
; BL = 10001000b
; BL = 00010000b , CF=1
; BL = 00100001b , CF=0
27. IntToBinStr
Convert an integer entered by user into a binary string
Hints:
First initialize the resultant string by zero characters
Then, continuously left shift the number till it becomes zero
If the carry flag after each shift is set, then change
corresponding character in the string to ‘1’
Enter an integer: 12
00000000000000000000000000001100
JC jump if carry flag = 1
JNC jump if carry flag = 0
28. INCLUDE Irvine32.inc
.data
promptMsg byte "Enter an integer: ", 0
strResult byte 32 dup('0'), 0 ;initialize string by '0' characters
.code
IntToBinStr PROTO number:DWORD, strBin:PTR BYTE
main PROC
mov edx, offset promptMsg
call writestring
call readint ; number is stored in eax
INVOKE IntToBinStr, eax, offset strResult
mov edx, offset strResult ; disaply the result
call writestring
call Crlf
exit
main ENDP
29. IntToBinStr PROC number:DWORD, strBin:PTR BYTE
push esi
mov esi, strBin
l1:
shl number, 1;Left-shift number to get the most significant bit in
CF
jnc skip ;If CF=0, leave this char in string as '0'
mov byte ptr [esi], '1' ;Otherwise, make it '1'
skip:
inc esi ;Move to the next char in strBin
cmp number, 0
jne l1 ;if eax is zero, stop (no need to continue)
pop esi
ret
IntToBinStr ENDP
END main
32. What is the difference between
SHL & MUL?
SHL, is concerned in
multiplication by power
of twos ONLY
MUL, can multiply by
any number (Generic)
33. Only one operand? … YES
The instructions take only one operand which is the
multiplier
Notes: 3*5
1. The multiplicand is assumed to be stored in specific
register
2. Also, operation results will be stored in specific
register(s) not in the given operand.
The locations of the second operand (multiplicand) and
operation result differ according to the size of the given operand
multiplicand
multiplier
34. Operand Sizes
1. The registers holding the product are twice the size of
multiplicand and the multiplier, guaranteeing that overflow will
never occur.
2. The product value is divided into two halves: upper and lower.
The upper half is AH, DX, and EDX in case if the product value is
AX, DX:AX, and EDX:EAX respectively
3. (MUL) Overflow (OF) and carry (CF) flags are set if the upper half
is not equal to zero.
4. (IMUL) Overflow and carry flags are set if the upper half is not
sign-extension of the lower half of product.
36. Exercise
mov AL, 48
mov BL, 4
imul BL
mov AL, -4
mov BL, 4
imul BL
;AX = 00C0 = (+192)10, OF = 1
;Note that +192 does not fit in AL
(lower half of product) as a signed
integer, so OF=1
;AX = FFF0 = (-16)10, OF = 0
;Note that even AH (upper half of
product)is not equal to zero but it is
just sign-
;extension for AL, so OF=0
+192
SBYTE Range
+127 To -128
38. DIV & IDIV
Where r/m8 means 8-bit register or memory byte, r/m16
means 16-bit register or memory word, and r/m32
means 32-bit register or memory double word.
DIV/IDIV r/m8 | r/m16 | r/m32
39. Operand Sizes
The registers holding the quotient are half the size of
dividend, assuming result value will be smaller enough to
fit in the register… BUT
This assumption is not always true
40. DIV & IDIV Quirks
1. If the quotient is too large to fit into destination
operand, a division overflow error occurs causing the
current program halts!
2. If the divisor is zero, an integer divide by zero error
occurs causing the current program halts!
3. A very common mistake is to forget to initialize DX or
EDX before use 16-bit or 32-bit division.
41. Key Inst.
In IDIV instruction, which used in signed division,
dividend should be well initialized to preserve the sign of
dividend. There are three instructions extends the sign
bit in AL, AX, and EAX to AX, DX, and EDX respectively
42. Exercise
MOV AX, 82
MOV BL, 4
DIV BL
MOV DX, 0
MOV AX, 82
MOV BX, 4
DIV BX
;Even 82 fit in AL, you should
MOV it in AX to initialize AH too
;AL (quotient) = 20,
;AH (remainder) = 2
;As we use 16-bit division, we
should initialize DX too
;AX (quotient) = 20,
;DX (remainder) = 2
43. Exercise
MOV AL, -100
CBW
MOV BL, 2
IDIV BL
MOV AX, -100
MOV BL, 2
IDIV BL
;We have to extend the sign to AX
;AL(quotient)= CEh = -50,
;AH (remainder) = 0
;Instead of use of CBW, move -100
to AX directly
;AL(quotient)= CEh = -50,
;AH (remainder) = 0
46. Binary Search Algorithm
Prerequisite: Sorted Array (Assume Ascending)
Receives: Search For “value”
Returns: The index of the value or -1 if not exists
47. int BSearch(int values[], int count, int SearchVal)
{
int first = 0;
int last = count - 1;
while (first <= last)
{
int mid = (last + first) / 2;
if (values[mid] < SearchVal)
first = mid + 1;
else if (values[mid] > SearchVal)
last = mid - 1;
else
return mid;
}
return -1;
}
49. .data
s1 BYTE "Enter a value to search for: ",0
s2 BYTE "This value in index: ",0
arr1 DWORD 10, 20, 30, 40, 50
.code
BinarySearch PROC USES esi edi ebx ecx, arr:PTR DWORD,
count:DWORD, value:DWORD
mov esi, 0;ESI: first index (initially = 0)
mov edi, count
dec edi ;EDI: last index (initially = count -1)
mov ecx, value ;ECX: the search value
mov eax, arr ;EAX: pointer for the array, actual
address
.while esi <= edi
mov ebx, esi
add ebx, edi
shr ebx, 1 ;EBX: mid index = (first + last)/2
50. ;[eax+ebx*4] is the current mid value
.IF [eax+ebx*4] < ecx
mov esi, ebx ;first = mid + 1
inc esi
.elseif [eax+ebx*4] > ecx
mov edi, ebx ;last = mid - 1
dec edi
.else
mov eax, ebx ;Found: EAX = mid index
jmp return
.endif
.endw
mov eax, -1;Not Found: EAX = -1
return:
ret
BinarySearch ENDP
51. main proc
mov edx, offset s1
call writestring
call readdec
INVOKE BinarySearch, offset arr1, lengthof arr1, eax
mov edx, offset s2
call writestring
call writeInt
call CrLf
exit
main endp
END main