汇编指令

待条件的数据传输指令

mov

1
2
3
4
5
mov         ; 传送指令
mov ax, 8 ; (ax) = 8
mov ax, bx ; (ax) = (bx)
MOVSX R16/R32, OPS ; 符号扩展传送
MOVZX R16/R32, OPS ; 0扩展传送

条件转移指令

1
2
3
4
5
6
7
8
使用单个标志位判断转移条件是否成立:
cmove/cmovz、cmovc、cmovs、cmovo、cmovp
条件:ZF=1 CF=1 SF=1 OF=1 PF=1
cmovne/cmovnz、cmovnc、cmovns、cmovno、cmovnp
条件:ZF=0 CF=0 SF=0 OF=0 PF=0

使用多个标志位判断转移条件是否成立:

add 和 sub

1
2
3
4
5
6
add         ; 加法运算指令
add ax, bx ; (ax) = (ax) + (bx)


sub ; 减法运算指令
sub ax, bx ; (ax) = (ax) - (bx)

push 和 pop

1
2
3
4
5
6
7
push        ; 进栈指令
pop ; 出栈指令
; 比如:
mov ax, 1000h
mov ds, ax ; 内存单元的段地址要放在 ds 中
push [0] ; 将 1000:0 处的字压入栈中
pop [2] ; 出栈,出栈的数据送入 1000:2

loop

1
2
3
loop        ; 循环指令
; 格式:loop 标号((cx)=(cx)-1,如果(cx)!=0,则转移到标号处执行)
; 功能:使转移标号与 loop 指令间的指令循环执行 cx 次

and

1
2
3
4
5
and         ; 逻辑“与”指令
; 功能:按位进行“与”运算
mov al, 01100011B
and al, 00111011B
; 结果:al = 00100011B

or

1
2
3
4
5
or          ; 逻辑“或”指令
; 功能:按位进行“或”运算
mov al, 01100011B
or al, 00111011B
; 结果:al = 01111011B

div

1
2
3
4
5
6
div         ; 除法指令
; a / b => a 是被除数,b 是除数
; 被除数:默认放在 ax(被除数16位)或 dx 和 ax(被除数32位)中
; 除数:有 8 位和 16 位两种,存放在 reg 或者内存单元中
; 结果:如果除数为 8 位,则 al 存放商,ah 存放余数
; 如果除数为 16 位,则 ax 存放商,dx 存放余数

db、dw 和 dd

1
2
3
4
5
6
7
db dw dd    ; 伪指令
; db 字节型 dw 字型 dd 双字型
data segment
db 1 ; 01h
dw 1 ; 0001h
dd 1 ; 0000_0001h
data ends

dup

1
2
3
dup         ; 伪指令
; 功能:用来进行数据的重复
db 3 dup (0); 定义了 3 个字节,值都为 0 ,等于 db 0, 0, 0

offset

1
2
offset      ; 操作符
; 功能:取得标号的偏移地址

inc 和 dec

1
2
3
4
inc         
; 格式:inc ax => (ax) = (ax) + 1
dec
; 格式:dec ax => (ax) = (ax) - 1

jmp

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
jmp         ; 无条件转移指令
; 可以只修改 ip :
jmp ax ; = mov ip, ax
; 也可以同时修改 cs 和 ip :
jmp 1000:0 ; cs = 1000, ip = 0

; 语法:jmp short 标号
; 功能:转到标号处执行指令
; 语法:jmp far ptr 标号
; (CS)=标号所在段的段地址,(IP)=标号在段中的偏移地址
; 语法:jmp word ptr 内存单元地址
; 功能:从内存单元地址处开始存放着一个字,是转移的目的偏移地址
; 比如:
mov ax, 0123h
mov [bx], ax
jmp word ptr [bx]
; 执行后 (ip) = 0123h
; 语法:jmp dword ptr 内存单元地址
; 功能:从内存单元地址处开始存放着两个字,
; 高地址处的字是转移的目的段地址,低地址处是转移的目的偏移地址
; (CS) = (内存单元地址+2),(IP) = (内存单元地址)
; 即 cs 在高位,ip 在低位
; 比如:
mov ax, 0123h
mov ds:[0], ax
mov word ptr ds:[2], 0
jmp dword ptr ds:[0]
; 执行后,(cs)=0, (ip)=0123h, cs:ip 指向 0000:0123

jcxz

1
2
3
4
jcxz        ; 条件转移指令
; 指令格式:jcxz 标号(如果(cx)=0,则转移到标号处执行)
; 当(cx)!=0时,什么也不做
; 即 jcxz 标号 = if ((cx)==0) jmp short 标号

ret 和 retf

1
2
3
4
5
6
7
8
ret         ; 转移指令
; 功能:利用栈中的数据,修改 ip 的内容
; cpu 执行 ret 指令时,相当于 pop ip


retf ; 转移指令
; 功能:利用栈中的数据,修改CS和IP的内容
; cpu 执行 retf 指令时,相当于 pop ip pop cs

call

1
2
3
4
5
6
7
8
9
10
11
call        ; 转移指令
; 功能:(1)将当前的 ip 或者 cs 和 ip 压入栈中
; (2)转移
; 注意:call 指令不能实现短转移
; 格式:call 标号 => push IP jmp near ptr 标号
; 格式:call far 标号 => push cs push ip jmp far ptr 标号
; 格式:call 16 位 reg => push ip jmp 16 位 reg
; 格式:call word ptr 内存单元地址
; => push ip jmp word ptr 内存单元地址
; 格式:call dword ptr 内存单元地址
; => push cs push ip jmp dword ptr 内存单元地址

mul

1
2
3
4
5
6
7
8
9
10
11
12
13
mul         ; 乘法指令
; (1)两个相乘的数,要么都是 8 位,要么都是 16
; 如果都是 8 位,则一个存放在 al 中,另一个存放在 8 位 reg 或内存字节单元中
; 如果是 16 位,则一个存放在 ax 中,另一个存放在 16 位 reg 或内存字节单元中
; (2)结果:如果是 8 位乘法,结果存放在 ax 中
; 如果是 16 位乘法,结果的高位存放在 dx 中,低位存放在 ax 中
; 格式:mul reg 或者 mul 内存单元
; 比如:
mul byte ptr ds:[0]
; 含义:(ax) = (al) * ((ds)*16+0)
mul word ptr [bx+si+8]
; 含义:(ax) = (ax)*((ds)*16+(bx)+(si)+8)结果的低 16
; (dx) = (ax)*((ds)*16+(bx)+(si)+8)结果的高 16

标志寄存器

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
zf          ; 零标志位(zero flag)
; 功能:记录相关指令执行后,结果是否为 0
; 若是,则 zf = 1,反之,zf = 0
; 比如:
mov ax, 1
sub ax, 1
; 执行后,结果为 0 ,则 zf = 1

pf ; 奇偶标志位(parity flag)
; 功能:记录相关指令执行后,其结果的所有 bit 位中 1 的个数是否为偶数
; 若 1 的个数为偶数,pf = 1,若为奇数,那么 pf = 0
; 比如:
mov ax, 1
add al, 10
; 执行后,结果为 0000_1011B,结果有 31 ,则 pf = 0

sf ; 符号标志位(sign flag)
; 功能:记录相关指令执行后,其结果是否为负
; 若结果为负,sf = 1;否则 sf = 0
; 比如:
mov al, 10000001B
add al, 1
; 执行后,结果为 1000_0010B,sf = 1

cf ; 进位标志位(carry flag)
; 功能:在进行无符号运算时
; 它记录了运算结果的最高有效位向更高有效位的进位值,或从更高位的借位值
; 若产生进位或借位,则 cf = 1,反之,cf = 0
; 比如:
mov al, 97h
sub al, 98h ; 执行后,(al) = ffh,cf = 1
sub al, al ; 执行后,(al) = 0,cf = 0

of ; 标志溢出位(overflow flag)
; 功能:记录了有符号数运算的结果是否发生了溢出
; 若发生了溢出,则 of = 1;反之,of = 0
; 比如:
mov al, 98
add al, 99
; (al) = (al) + 99 = 98 + 99 = 197 超出 -128 ~ 127 的范围
; 执行后将产生溢出,of = 1

df ; 方向标志位(direction flag)
; 功能:在串处理指令中,控制每次操作后 si、di 的增减
; df = 0,每次操作后 di、si 递增
; df = 1,每次操作后 di、si 递减

adc

1
2
3
4
5
6
7
8
9
adc         ; 带进位加法指令
; 指令格式:adc ax, bx
; 功能:(ax) = (ax) + (bx) + cf
; 比如:
mov ax, 2
mov bx, 1
sub, bx, ax ; 借位,cf = 1
adc ax, 1
; 执行后,(ax) = (ax) + 1 + cf = 2 + 1 + 1 = 4

sbb

1
2
3
sbb         ; 带进位减法指令
; 指令格式:sbb ax, bx
; 功能:(ax) = (ax) - (bx) - cf

cmp

1
2
3
4
5
6
7
8
cmp         ; 比较指令
; 格式:cmp ax, ax
; 功能:做 (ax)-(ax) 的运算,但并不在 ax 中保存结果
; 比如:
mov ax, 8
mov bx, 3
cmp, ax, bx
; (ax) = 8, zf = 0, pf = 1, sf = 0, cf = 0, 0f = 0

movsb 和 movsw

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
movsb       ; 串传送指令
; 格式:movsb
; 功能:执行 movsb 指令相当于进行下面几步操作:
mov es:[di], byte ptr ds:[si] ; 8086 并不支持的这样的指令,仅作描述
if df = 0:
inc si
inc di
if df = 1:
dec si
dec di
; 即:movsb 的功能是将 ds:si 指向的内存单元中的字节送入 es:di 中
; 然后根据寄存器 df 位的值,将 si 和 di 递增或递减

movsw ; 串传送指令
; 格式:movsw
; 功能:执行 movsw 指令相当于进行下面几步操作
mov es:[di], word ptr ds:[si] ; 8086 并不支持的这样的指令,仅作描述
if df = 0:
add si, 2
add di, 2
if df = 1:
sub si, 2
sub di, 2

; 一般来说,movsb 和 movsw 都和 rep 配合使用
; 格式:rep movsb
; 功能:s:movsb loop s

cld 和 std

1
2
cld         ; 将 df 位置 0
std ; 将 df 位置 1

pushf 和 popf

1
2
3
4
pushf       ; 进栈指令
; 功能:将标志寄存器的值压栈
popf ; 出栈指令
; 功能:从栈中弹出数据,送入标志寄存器中

iret

1
2
iret        ; 转移指令
; 功能:pop ip pop cs popf

int

1
2
3
int         ; 中断指令
; 格式:int n (n 为中断类型码)
; 功能:引发中断过程

in 和 out

1
2
3
4
5
in al, 60h  ; 从 60h 号端口读入一个字节
out 20h, al ; 从 20h 号端口写入一个字节
; 注意:在 in 和 out 指令中,只能使用 ax 或 al 来存放从端口中读入的数据
; 或要发送到端口中的数据
; 访问 8 位端口时用 al,访问 16 位端口时用 ax

shl 和 shr

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
shl         ; 逻辑移位指令(逻辑左移)
; 功能:
; 1)将一个寄存器或内存单元中的数据向左移位
; 2)将最后移出的一位写入 cf 中
; 3)最低位用 0 补充
; 比如
mov al, 01001000B
shl al, 1
; 执行后 (al) = 1001_0000b, cf = 0
; 如果移位大于 1 时,必须将移动位数放在 cl 中:
mov al, 01010001B
mov cl, 3
shl al, cl
; 执行后(al)= 1000_1000b
; 因为最后移出的一位是 0 ,所以 cf = 0

shr ; 逻辑移位指令(逻辑右移)
; 类似地,便不作过多描述

条件转移指令

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
; 条件转移指令:

je ; e => equal
; 含义:等于则转移
; 检测的相关标志位: zf = 1

jne
; 含义:不等于则转移
; 检测的相关标志位: zf = 0

jb ; b => below
; 含义:低于则转移
; 检测的相关标志位: cf = 1

jnb
; 含义:不低于则转移
; 检测的相关标志位: cf = 0

ja ; a => above
; 含义:高于则转移
; 检测的相关标志位: cf = 0 且 zf = 0

jna
; 含义:不高于则转移
; 检测的相关标志位: cf = 1 且 zf = 1

jc
; 含义:有进位则跳转

jnc
; 含义:无进位则跳转

daa和das

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
daa
; 功能:调整 AL 的值,
; 该值是由指令 ADD 或 ADC 运算两个压缩型 BCD 码所得到的结果
; 例如:
mov al, 43h
mov bl, 29h
add al, bl ; al=6ch
daa ; 调整后,al=72h

das
; 功能:调整 AL 的值,
; 该值是由指令 SUB 或 SBB 运算两个压缩型 BCD 码所得到的结果
; 例如:
mov al, 43h
mov bl, 29h
sub al, bl ; al=1ah
das ; 调整后,al=14h

汇编指令
http://example.com/2024/04/01/汇编指令/
作者
icyyoung
发布于
2024年4月1日
许可协议