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