您的位置:首页 > 其它

学 Win32 汇编[27] - 乘除指令: MUL、IMUL、DIV、IDIV

2010-04-15 21:17 309 查看
MUL: 无符号乘
;影响 OF、CF 标志位
;指令格式:
;MUL r/m  ;参数是乘数

;如果参数是 r8/m8,   将把  AL 做乘数, 结果放在 AX
;如果参数是 r16/m16, 将把  AX 做乘数, 结果放在 EAX
;如果参数是 r32/m32, 将把 EAX 做乘数, 结果放在 EDX:EAX

; Test27_1.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.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

;把上面的例子稍作修改(mul -> imul), 得到了不同的结果:

; Test27_2.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
val dd 8
.code
main proc
;8 位
mov al, 0FFh
imul byte ptr val
PrintHex ax  ;FFF8

;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


IMUL: 有符号乘
;影响 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)

;其中常数 i 的位数可以 <= 但不能 > 其他操作数

; Test27_3.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.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

;MUL 与 IMUL 结果的一致于不一致:

; Test27_4.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.data
val db 7Fh
.code
main proc
;如果操作数都没有符号位, 结果一致
mov al, 7Fh
mul val
PrintHex ax ;3F01

mov al, 7Fh
imul val
PrintHex ax ;3F01

;如果操作数的其中之一有符号位, 结果不一致
mov al, 80h
mul val
PrintHex ax ;3F80

mov al, 80h
imul val
PrintHex ax ;C080

;如果操作数都有符号位, 结果也一致
inc val
mov al, 80h
mul val
PrintHex ax ;4000

mov al, 80h
imul val
PrintHex ax ;4000
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

; DIV 测试
; Test27_5.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

.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

;IDIV 测试
; Test27_6.asm
.386
.model flat, stdcall

include    windows.inc
include    kernel32.inc
include    masm32.inc
include    debug.inc
includelib kernel32.lib
includelib masm32.lib
includelib debug.lib

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