ASM指令笔记0

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
.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)

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
.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

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

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
.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



shl,shr,sal,sar:移位指令分为逻辑移位指令和算术移位指令

  • shl 与 shr 属于逻辑移位指令

    shl逻辑左移指令

将寄存器或内存单元的数据左移 最低位用 0 补充 最高位进入 CF

1
2
3
4
5
6
7
例子:

mov ax,8fh ;mov ax,1000 1111b
shl ax,1 ;将ax左移一位

执行后 (ax) = 0001 1110b ;1eh
CF = 1

如果我们需要移动的位数大于1时,需要将移动位数存入 cl 例子:

比如说我们要移动 4 位

1
2
3
4
5
6
mov cl,4
mov ax,9fh ;mov ax,1000 1111b
shl ax,cl ;左移位数为 cl 里的数据

执行后 (ax) = 1111 0000b ;f0h
CF = 1

shr逻辑右移指令

将寄存器或内存单元的数据右移 最低位用 0 补充 最低位进入 CF

sal 与 sar 属于算术移位指令

  • sal 算术左移指令

功能与shl相同

  • sar 算术右移指令

基本与shr相同 与shr补 0 不同,sar补位时最高位不变

inc: 加1指令

使目标寄存器数值加一