Assembly Language for x86 Processors
7th Edition
Kip R. Irvine
Chapter 7: Integer Arithmetic
Slides prepared by the author
Revision date: 1/15/2014
(c) Pearson Education, 2014. All rights reserved. You may modify and copy this slide show for your personal use, or for
use in the classroom, as long as this copyright statement, the author's name, and the title are not changed.
SHLD Instruction
• Shifts a destination operand a given number of bits to
the left
• The bit positions opened up by the shift are filled by
the most significant bits of the source operand
• The source operand is not affected
• Syntax:
SHLD destination, source, count
• Operand types:
SHLD reg16/32, reg16/32, imm8/CL
SHLD mem16/32, reg16/32, imm8/CL
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 2
SHLD Example
Shift count of 1:
mov al,11100000b
mov bl,10011101b
shld al,bl,1
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 3
Another SHLD Example
Shift wval 4 bits to the left and replace its lowest 4 bits with
the high 4 bits of AX:
.data
wval AX
wval WORD 9BA6h
Before: 9BA6 AC36
.code
mov ax,0AC36h After: BA6A AC36
shld wval,ax,4
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 4
SHRD Instruction
• Shifts a destination operand a given number of bits to
the right
• The bit positions opened up by the shift are filled by
the least significant bits of the source operand
• The source operand is not affected
• Syntax:
SHRD destination, source, count
• Operand types:
SHRD reg16/32, reg16/32, imm8/CL
SHRD mem16/32, reg16/32, imm8/CL
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 5
SHRD Example
Shift count of 1:
mov al,11000001b
mov bl,00011101b
shrd al,bl,1
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 6
Another SHRD Example
Shift AX 4 bits to the right and replace its highest 4 bits with
the low 4 bits of DX:
mov ax,234Bh DX AX
Before: 7654 234B
mov dx,7654h
shrd ax,dx,4 7654 4234
After:
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 7
Your turn . . .
Indicate the hexadecimal values of each destination
operand:
mov ax,7C36h
mov dx,9FA6h
shld dx,ax,4 ; DX = FA67h
shrd dx,ax,8 ; DX = 36FAh
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 8
Shift and Rotate Applications
• Shifting Multiple Doublewords
• Binary Multiplication
• Displaying Binary Bits
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 9
Shifting Multiple Doublewords
• Programs sometimes need to shift all bits within an
array, as one might when moving a bitmapped
graphic image from one screen location to another.
• The following shifts an array of 3 doublewords 1 bit to
the right:
.data
ArraySize = 3
array DWORD ArraySize DUP(99999999h) ; 1001 1001...
.code
mov esi,0
shr array[esi + 8],1 ; high dword
rcr array[esi + 4],1 ; middle dword, include Carry
rcr array[esi],1 ; low dword, include Carry
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 10
Binary Multiplication
• mutiply 123 * 36
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 11
Binary Multiplication
• We already know that SHL performs unsigned
multiplication efficiently when the multiplier is a power
of 2.
• You can factor any binary number into powers of 2.
• For example, to multiply EAX * 36, factor 36 into 32 + 4
and use the distributive property of multiplication to
carry out the operation:
EAX * 36 mov eax,123
= EAX * (32 + 4) mov ebx,eax
= (EAX * 32)+(EAX * 4) shl eax,5 ; mult by 25
shl ebx,2 ; mult by 22
add eax,ebx
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 12
Your turn . . .
Multiply AX by 26, using shifting and addition instructions.
Hint: 26 = 16 + 8 + 2.
mov ax,2 ; test value
mov dx,ax
shl dx,4 ; AX * 16
push edx ; save for later
mov dx,ax
shl dx,3 ; AX * 8
shl ax,1 ; AX * 2
add ax,dx ; AX * 10
pop edx ; recall AX * 16
add ax,dx ; AX * 26
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 13
Multiplication and Division Instructions
• MUL Instruction
• IMUL Instruction
• DIV Instruction
• Signed Integer Division
• CBW, CWD, CDQ Instructions
• IDIV Instruction
• Implementing Arithmetic Expressions
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 14
MUL Instruction
• In 32-bit mode, MUL (unsigned multiply) instruction multiplies an
8-, 16-, or 32-bit operand by either AL, AX, or EAX.
• The instruction formats are:
MUL r/m8
MUL r/m16
MUL r/m32
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 15
64-Bit MUL Instruction
• In 64-bit mode, MUL (unsigned multiply) instruction multiplies a
64-bit operand by RAX, producing a 128-bit product.
• The instruction formats are:
MUL r/m64
Example:
mov rax,0FFFF0000FFFF0000h
mov rbx,2
mul rbx ; RDX:RAX = 0000000000000001FFFE0001FFFE0000
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 16
MUL Examples
100h * 2000h, using 16-bit operands:
.data
val1 WORD 2000h The Carry flag
val2 WORD 100h indicates whether or
not the upper half of
.code
the product contains
mov ax,val1 significant digits.
mul val2 ; DX:AX = 00200000h, CF=1
12345h * 1000h, using 32-bit operands:
mov eax,12345h
mov ebx,1000h
mul ebx ; EDX:EAX = 0000000012345000h, CF=0
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 17
Your turn . . .
What will be the hexadecimal values of DX, AX, and the Carry
flag after the following instructions execute?
mov ax,1234h
mov bx,100h
mul bx
DX = 0012h, AX = 3400h, CF = 1
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 18
Your turn . . .
What will be the hexadecimal values of EDX, EAX, and the
Carry flag after the following instructions execute?
mov eax,00128765h
mov ecx,10000h
mul ecx
EDX = 00000012h, EAX = 87650000h, CF = 1
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 19
IMUL Instruction
• IMUL (signed integer multiply ) multiplies an 8-, 16-,
or 32-bit signed operand by either AL, AX, or EAX
• Preserves the sign of the product by sign-extending it
into the upper half of the destination register
Example: multiply 48 * 4, using 8-bit operands:
mov al,48
mov bl,4
imul bl ; AX = 00C0h, OF=1
OF=1 because AH is not a sign extension of AL.
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 20
Using IMUL in 64-Bit Mode
• You can use 64-bit operands. In the two-operand
format, a 64-bit register or memory operand is
multiplied against RDX
• 128-bit product produced in RDX:RAX
• The three-operand format produces a 64-bit product
in RAX
.data
multiplicand QWORD -16
.code
imul rax, multiplicand, 4 ; RAX = FFFFFFFFFFFFFFC0 (-64)
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 21
IMUL Examples
Multiply 4,823,424 * −423:
mov eax,4823424
mov ebx,-423
imul ebx ; EDX:EAX = FFFFFFFF86635D80h, OF=0
OF=0 because EDX is a sign extension of EAX.
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 22
Your turn . . .
What will be the hexadecimal values of DX, AX, and the Carry
flag after the following instructions execute?
mov ax,8760h
mov bx,100h
imul bx
DX = FF87h, AX = 6000h, OF = 1
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 23
DIV Instruction
• The DIV (unsigned divide) instruction performs 8-bit,
16-bit, and 32-bit division on unsigned integers
• A single operand is supplied (register or memory
operand), which is assumed to be the divisor
• Instruction formats:
DIV reg/mem8
DIV reg/mem16
Default Operands:
DIV reg/mem32
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 24
DIV Examples
Divide 8003h by 100h, using 16-bit operands:
mov dx,0 ; clear dividend, high
mov ax,8003h ; dividend, low
mov cx,100h ; divisor
div cx ; AX = 0080h, DX = 3
Same division, using 32-bit operands:
mov edx,0 ; clear dividend, high
mov eax,8003h ; dividend, low
mov ecx,100h ; divisor
div ecx ; EAX = 00000080h, DX = 3
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 25
64-Bit DIV Example
Divide 000001080000000033300020h by
00010000h:
.data
dividend_hi QWORD 00000108h
dividend_lo QWORD 33300020h
divisor QWORD 00010000h
.code
mov rdx, dividend_hi
mov rax, dividend_lo
div divisor ; RAX = quotient
; RDX = remainder
quotient: 0108000000003330h
remainder: 0000000000000020h
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 26
Your turn . . .
What will be the hexadecimal values of DX and AX
after the following instructions execute? Or, if divide
overflow occurs, you can indicate that as your answer:
mov dx,0087h
mov ax,6000h
mov bx,100h
div bx
DX = 0000h, AX = 8760h
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 27
Your turn . . .
What will be the hexadecimal values of DX and AX
after the following instructions execute? Or, if divide
overflow occurs, you can indicate that as your answer:
mov dx,0087h
mov ax,6002h
mov bx,10h
div bx
Divide Overflow
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 28
Signed Integer Division (IDIV)
• Signed integers must be sign-extended before
division takes place
• fill high byte/word/doubleword with a copy of the low
byte/word/doubleword's sign bit
• For example, the high byte contains a copy of the
sign bit from the low byte:
10001111
11111111 10001111
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 29
CBW, CWD, CDQ Instructions
• The CBW, CWD, and CDQ instructions provide
important sign-extension operations:
• CBW (convert byte to word) extends AL into AH
• CWD (convert word to doubleword) extends AX into DX
• CDQ (convert doubleword to quadword) extends EAX into EDX
• Example:
.data
dwordVal SDWORD -101 ; FFFFFF9Bh
.code
mov eax,dwordVal
cdq ; EDX:EAX = FFFFFFFFFFFFFF9Bh
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 30
IDIV Instruction
• IDIV (signed divide) performs signed integer division
• Same syntax and operands as DIV instruction
Example: 8-bit division of –48 by 5
mov al,-48
cbw ; extend AL into AH
mov bl,5
idiv bl ; AL = -9, AH = -3
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 31
IDIV Examples
Example: 16-bit division of –48 by 5
mov ax,-48
cwd ; extend AX into DX
mov bx,5
idiv bx ; AX = -9, DX = -3
Example: 32-bit division of –48 by 5
mov eax,-48
cdq ; extend EAX into EDX
mov ebx,5
idiv ebx ; EAX = -9, EDX = -3
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 32
Your turn . . .
What will be the hexadecimal values of DX and AX
after the following instructions execute? Or, if divide
overflow occurs, you can indicate that as your answer:
mov ax,0FDFFh ; -513
cwd
mov bx,100h
idiv bx
DX = FFFFh (−1), AX = FFFEh (−2)
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 33
Unsigned Arithmetic Expressions
• Some good reasons to learn how to implement
integer expressions:
• Learn how do compilers do it
• Test your understanding of MUL, IMUL, DIV, IDIV
• Check for overflow (Carry and Overflow flags)
Example: var4 = (var1 + var2) * var3
; Assume unsigned operands
mov eax,var1
add eax,var2 ; EAX = var1 + var2
mul var3 ; EAX = EAX * var3
jc TooBig ; check for carry
mov var4,eax ; save product
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 34
Signed Arithmetic Expressions (1 of 2)
Example: eax = (-var1 * var2) + var3
mov eax,var1
neg eax
imul var2
jo TooBig ; check for overflow
add eax,var3
jo TooBig ; check for overflow
Example: var4 = (var1 * 5) / (var2 – 3)
mov eax,var1 ; left side
mov ebx,5
imul ebx ; EDX:EAX = product
mov ebx,var2 ; right side
sub ebx,3
idiv ebx ; EAX = quotient
mov var4,eax
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 35
Signed Arithmetic Expressions (2 of 2)
Example: var4 = (var1 * -5) / (-var2 % var3);
mov eax,var2 ; begin right side
neg eax
cdq ; sign-extend dividend
idiv var3 ; EDX = remainder
mov ebx,edx ; EBX = right side
mov eax,-5 ; begin left side
imul var1 ; EDX:EAX = left side
idiv ebx ; final division
mov var4,eax ; quotient
Sometimes it's easiest to calculate the right-hand term of an
expression first.
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 36
Your turn . . .
Implement the following expression using signed 32-bit
integers:
eax = (ebx * 20) / ecx
mov eax,20
imul ebx
idiv ecx
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 37
Your turn . . .
Implement the following expression using signed 32-bit
integers. Save and restore ECX and EDX:
eax = (ecx * edx) / eax
push edx
push eax ; EAX needed later
mov eax,ecx
imul edx ; left side: EDX:EAX
pop ebx ; saved value of EAX
idiv ebx ; EAX = quotient
pop edx ; restore EDX, ECX
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 38
Your turn . . .
Implement the following expression using signed 32-bit
integers. Do not modify any variables other than var3:
var3 = (var1 * -var2) / (var3 – ebx)
mov eax,var1
mov edx,var2
neg edx
imul edx ; left side: EDX:EAX
mov ecx,var3
sub ecx,ebx
idiv ecx ; EAX = quotient
mov var3,eax
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 39
55 74 67 61 6E 67 65 6E
Irvine, Kip R. Assembly Language for x86 Processors 7/e, 2014. 40