您的位置:首页 > 其它

Win32ASM学习[16] :乘除指令: MUL、IMUL、DIV、IDIV

2011-12-04 19:29 609 查看
----------------------------------------------------------------------------------------------------------------------------------------------------------------------

一. 无符号数乘法指令 MUL(MULtiply)

格式: MUL OPRD

功能: 乘法操作.

说明: 1. OPRD为通用寄存器或存储器操作数.

2. OPRD为源操作数,即作乘数.目的操作数是隐含的,即被乘数总是指定为累加器AX 或AL的内容.

3. 16位乘法时,AX中为被乘数.8位乘法时,AL为被乘数.当16位乘法时,32位的乘积存于DX及AX中;8位乘法的16位乘积存于AX中.

4. 操作过程: 字节相乘:(AX)<--(AL)*OPRD,当结果的高位字节(AH)不等于0时,则CF=1、OF=1.字相乘: (DX)(AX)<--(AX)*OPRD,当(DX)不等0时,则CF=1、OF=1

5. 示例 1: MUL BETA[BX]

MUL DI

MUL BYTE PTR ALFA

示例 2: 设在W1和W2字单元中各有一个16位数,若求其乘积并存于W3开始的字单元中,可用以下指令组实现:

MOV AX,W1

MUL W2

MOV W3,AX

MOV W3+2,DX

---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------

.data

val dd 8

.code

main proc

;8 位

mov al, 0FFh

mul byte ptr val

PrintHex ax ;07F8

;16 位

mov ax, 0FFFFh

mul word ptr val

PrintHex dx ;0007

PrintHex ax ;FFF8

;32 位

mov eax, 0FFFFFFFFh

mul val

PrintHex edx ;00000007

PrintHex eax ;FFFFFFF8

ret

main endp

end main

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

二. 带符号数乘法指令 IMUL(Integer MULtiply)

格式: IMUL OPRD

功能: 完成两个带符号数的相乘

说明: 1. 其中OPRD为任一通用寄存器或存储器操作数.

2. MUL指令对带符号相乘时,不能得到正确的结果.

例如: (AL)=255

(CL)=255

MUL CL

(AX)=65025

注意: 这对无符号数讲,结果是正确的,但对带符号数讲,相当于(-1)*(-1)结果应为+1,而65025对应的带符号数为-511,显然是不正确的.

3. 8088/8086指令系统提供了专用的带符号数乘法和除法指令.IMUL即为带符号乘法指令,它能保证得到正确的带符号数的乘积.

操作过程:字节相乘:(AX)<--(AL)*OPRD

字相乘: (DX)(AX)<--(AX)*OPRD

4. 本指令影响标志位CF、OF.

;影响 OF、CF 标志位;第一种指令格式:

;IMUL
r/m ;单操作数;如果参数是
r8/m8, 将把 AL 做乘数, 结果放在 AX

;如果参数是
r16/m16, 将把 AX 做乘数, 结果放在 EAX

;如果参数是
r32/m32, 将把 EAX 做乘数, 结果放在 EDX:EAX

;以上这些都是和
MUL 一样的, 只是运算结果有时一样、有时不一样.

;IMUL
还有另外两种指令格式:

;IMUL
r16/r32, r16/r32/m16/m32/i

;双操作数, (1)*(2) -> (1)

;IMUL
r16/r32, r16/r32/m16/m32, i

;三操作数, (2)*(3) -> (1)

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

.data

val dd 8

.code

main proc

;8 位

mov al, 0FFh

PrintDec al

imul byte ptr val

PrintHex ax ;FFF8

PrintDec ax ;-8

;-------------------------

mov al,-8 ;F8

mul byte ptr val

PrintDec ax ;1984

PrintHex ax ;07C0

;-------------------------

;16 位

mov ax, 0FFFFh

imul word ptr val

PrintHex dx ;FFFF

PrintHex ax ;FFF8

;32 位

mov eax, 0FFFFFFFFh

imul val

PrintHex edx ;FFFFFFFF

PrintHex eax ;FFFFFFF8

ret

main endp

end main

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

.data

val dd 8

.code

main proc

;IMUL 两个操作数

mov eax, 7

imul eax, val

PrintDec eax ;56

;IMUL 三个操作数

imul eax, val, 9

PrintDec eax ;72

ret

main endp

end main

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

DIV、IDIV: 无符号除、有符号除

;它们没有定义对 EFLAGS 的影响

;它们的指令格式:

;DIV r/m ;参数是除数

;如果参数是 r8/m8, 将把 AX 做被除数; 商 -> AL, 余数 -> AH

;如果参数是 r16/m16, 将把 DX:AX 做被除数; 商 -> AX, 余数 -> DX

;如果参数是 r32/m32, 将把 EDX:EAX 做被除数; 商 -> EAX, 余数 -> EDX

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

.code

main proc

;除数是 8 位

mov ax, 17 ;被除数

mov cl, 3 ;除数

div cl

PrintDec al ;5 - 商

PrintDec ah ;2 - 余数

;除数是 16 位

mov dx, 0 ;

mov ax, 17 ;dx:ax 是被除数

mov cx, 3 ;cx 是除数

div cx

PrintDec ax ;5 - 商

PrintDec dx ;2 - 余数

;除数是 32 位

mov edx, 0 ;

mov eax, 17 ;edx:eax 是被除数

mov ecx, 3 ;ecx 是除数

div ecx

PrintDec eax ;5 - 商

PrintDec edx ;2 - 余数

ret

main endp

end main

----------------------------------------------------------------------------------------------------------------------------------------------------------------------

.code

main proc

;除数是 8 位

mov al, -17

cbw ;ax 是被除数

mov cl, 3 ;除数

idiv cl

PrintDec al ;-5 - 商

PrintDec ah ;-2 - 余数

;除数是 16 位

mov ax, -17

cwd ;dx:ax 是被除数

mov cx, 3 ;cx 是除数

idiv cx

PrintDec ax ;-5 - 商

PrintDec dx ;-2 - 余数

;除数是 32 位

mov eax, -17

cdq ;edx:eax 是被除数

mov ecx, 3 ;ecx 是除数

idiv ecx

PrintDec eax ;-5 - 商

PrintDec edx ;-2 - 余数

ret

main endp

end main

----------------------------------------------------------------------------------------------------------------------------------------------------------------------
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: