1
3.3 8086/8088指令系统
可分成如下 6类:
? 数据传送指令
? 算术运算指令
? 逻辑运算和移位指令
? 串操作指令
? 程序控制指令
? 处理器控制指令
2
3.3.1 数据传送指令
? 可实现
存储器 寄存器 I/O
? 数据传送指令又可分为如下四种:
? 通用传送
? 目标地址传送
? 标志传送
? 输入输出
3
1.通用传送指令
(1) MOV dest,src; dest←src
传送的是字节还是字取决于指令中涉及的寄
存器是 8位还是 16位 。
具体来说可实现:
① MOV mem/reg1,mem/reg2
指令中两操作数中至少有一个为寄存器
例, MOV CL,DL
MOV AX,BX
MOV [SI],CX
MOV CL,[BX+5]
4
② MOV reg,data ;立即数送寄存器
③ MOV mem,data ;立即数送存储单元
④ MOV acc,mem ;存储单元送累加器
⑤ MOV mem,acc ;累加器送存储单元
⑥ MOV segreg,mem/reg ;存储单元 /寄存器送
段寄存器
⑦ MOV mem/reg,segreg ;段寄存器送存储单
元 /寄存器
5
MOV指令使用规则:
1) IP不能作目的寄存器
2) 不允许 mem←mem
3) 不允许 segreg←segreg
4) 立即数不允许作为目的操作数
5) 不允许 segreg← 立即数
6) 源操作数与目的操作数类型要一致
6
几个不能传送的解决办法,用 AX作桥梁
?存储器 ← 存储器:
MOV AX,MEM1
MOV MEM2,AX
?段寄存器 ← 段寄存器:
MOV AX,DS
MOV ES,AX
?段寄存器 ← 立即数:
MOV AX,DATA
MOV DS,AX
7
?应用举例:将 1000H开始的 100个存储单元
全部填充为 ASCII码 2AH(*)。
程序段如下:
MOV DI,1000H
MOV CX,64H
MOV AL,2AH
AGAIN,MOV [DI],AL
INC DI
DEC CX
JNZ AGAIN
HLT
8
上程序段存放在 代码段 中,設 (CS)=109EH,
则各条指令存放地址如下:
CS, IP 指令
109E, 0100 MOV DI,1000H
109E, 0103 MOV CX,64H
109E, 0106 MOV AL,2AH
109E, 0108 MOV [DI],AL
109E, 010A INC DI
109E, 010B DEC CX
109E, 010C JNZ 0108
109E, 010E HLT
109E, 0110
9
写入 2AH(*)后,数据段中相应存储单元的内容改
变如下:
DS:1000 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
DS:1010 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
DS:1020 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
DS:1030 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
DS:1040 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
DS:1050 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A
DS:1060 2A 2A 2A 2A
10
什么是堆栈?
按, 后进先出 (LIFO)”方式工作的存储区
域 。 堆栈 以字为单位 进行压入弹出操作 。
为什么要设置堆栈?
为什么要按, 后进先出, 方式工作?
参见下图
(2) 堆栈操作指令
11
主程序
IP












主程序
IP
IP(下 )







IP’





2
IP’(下 )
执行子
程序 1







1
(a) (b)
子程序调用示意图
(a) 主程序调子程序; (b) 子程序嵌套示意图
IP(下 )
12
规定由 SS指示堆栈段的段基址, 堆栈指针 SP
始终指向堆栈的顶部, SP的初值规定了所用
堆栈区的大小 。 堆栈的最高地址叫栈底 。
SP
SS
堆栈段
进栈方向
退栈方向 栈底
栈顶
13
① 压栈指令
PUSH src ; src为 16位操作数
例,PUSH AX ;将 AX内容压栈
执行操作:( SP) -1← 高字节 AH
( SP) -2← 低字节 AL
(SP) ← ( SP) - 2
14
设( AX) =1020H,执行示意图如图
低地址 存储区
( SS段)
执行前
(AX)=1020
(SP)
存储区
( SS段)
进栈方向
执行后
20
10
(AL)
(AH)
2-8
PUSH AX指令执行示意图
(SP)-2
(SP)
高地址
低地址
高地址
(SP)-1
15
压栈指令的格式为:
PUSH reg
PUSH mem/reg
PUSH segreg
例如:
PUSH AX
PUSH [BX]
PUSH DS
注意进栈方向是 高地址 向 低地址 发展。
16
② 弹出指令
POP dest
例,POP BX ;将栈顶内容弹至 BX
执行操作,( BL) ← ( SP)
( BH) ← ( SP) +1
( SP) ← ( SP) +2
17
POP BX 的执行示意图如下图所示
低地址
存储区
( SS段)
出栈方向
执行前
20
10
POP BX指令执行示意图
(SP)
存储区
( SS段)
执行后
(BX)=1020
(SP)
(SP)+1
(SP)+2
BX
2010
高地址
低地址
高地址
18
堆栈指令使用时应注意几点:
① 堆栈操作总是按 字 进行
② 不能从栈顶弹出一个字给 CS
③ 堆栈指针为 SS:SP,SP永远指向栈顶
④ SP自动进行增减量 ( -2,+2)
19
格式,XCHG reg,mem/reg
功能:交换两操作数的内容 。
要求:两操作数中必须有一个在寄存器中;
操作数不能为段寄存器和立即数;
源和目地操作数类型要一致 。
举例,XCHG AX,BX
XCHG [2000],CL
(3)交换指令 XCHG
20
(4)查表指令 XLAT
执行的操作,AL←[(BX)+(AL)]
又叫 查表转换指令, 它可根据表项序号查
出表中对应代码的内容 。 执行时先将表的首
地址 ( 偏移地址 ) 送到 BX中, 表项序号存于
AL中 。
例如:内存数据段有一张 16进制数的
ASCII码表, 设首地址为 2000H,如欲查出表
中第 11个代码 ( 代码序号从 0开始 ) 即十六
进制数 B的 ASCII码 。 ASCII表在 DS段中, 并
假设 (DS)=4000H。 见下页图 。
‘ ’
21
30
31
32
...
39
41
42
...
45
46
...
42000H+0
42000H+0BH
‘0’
‘1’
‘2’
‘9’
‘A’
‘B’
‘E’
‘F’
十六进制数 ASCII码表
存储器
22
则可用如下几条指令实现,
MOV BX,2000H ;( BX) ← 表首地址
MOV AL,0BH ;( AL) ← 序号
XALT ; 查表转换
执行后得到:( AL) = 42H = ’ B’
注意:转换表长度最大为 256个表项 (字节 )。
23
(5)字节 -字转换指令
格式,CBW ;把 AL的符号位复制到 AH
CWD ;把 AX的符号位复制到 DX
用途:用于有符号数的除法。
例如,(AL) = A7H,则执行 CBW后,AH的内
容为 FFH。
24
2,输入输出( I/O)指令
只限于用 累加器 AL或 AX来传送信息 。
功能, (累加器 )←→I/O 端口
(1)输入指令 IN
格式,
IN acc,PORT ;PORT端口号 0~ 255
IN acc,DX ;DX表示的端口范围达 64K
例,IN AL,80H ;(AL) ← (80H端口 )
IN AL,DX ;(AL) ← ((DX))
25
例,OUT 68H,AX ;(69H,68H) ← ( AX)
OUT DX,AL ;((DX))←(AL)
在使用间接寻址的 IN/OUT指令时, 要事先用
传送指令把 I/O端口号设置到 DX寄存器, 如:
MOV DX,220H
IN AL,DX ;将 220H端口内容读入 AL
(2) 输出指令 OUT
格式,OUT port,acc
OUT DX,acc
26
3,地址传送指令
共有三条,
格式,LEA reg,mem ; 将指定存储器的 16位偏移
地址送指定寄存器
LDS reg,mem32; DS:reg←(mem 开始的四
个内存单元 )
LES reg,mem32; 同上, 但 DS改为 ES
要求 源操作数 必须是一个 内存操作数, 目的操作
数必须是一个 16位的通用寄存器 。
27
设,( SI) =1000H
则执行该指令后, ( BX) =1010H
注意以下两条指令差别:
LEA BX,BUFFER
MOV BX,BUFFER
前者表示将符号地址为 BUFFER的存储单元的
偏侈地址取到 BX中 ;后者表示将 BUFFER存储
单元中的内容取 到 BX中,
例,LEA BX,[SI+10H]
28
下面两条指令等效:
LEA BX,BUFFER
MOV BX,OFFSET BUFFER
其中 OFFSET BUFFER表示存储器单元 BUFFER
的偏移地址。
二者都可用于取 存储器单元的偏移地址,但
LEA指令可以取动态的地址,OFFSET只能取
静态的地址。
29
4.标志传送指令
共有四条:
(1)读标志指令 LAHF
LAHF把标志寄存器低 8位中的 5个标志位传
送到 AH中的指定位,如下图所示,
1D3D5D7D 6D 4D 2D 0D
OF DF IF TF SF ZF AF PF CF
AH
LAHF指令的功能
FLAG
30
(2)设置标志指令 SAHF
SAHF的功能与 LAHF的功能正好相反,
用图来示意, 只要将上图中 5个箭头方向反
一下即可 。
1D3D5D7D 6D 4D 2D 0D
OF DF IF TF SF ZF AF PF CF
AH
SAHF指令的功能
FLAG
31
执行的操作,(SP)-1← 标志寄存器高 8位
(SP)-2← 标志寄存器低 8位
(SP)←(SP) -2
(4)从栈顶弹出标志寄存器指令 POPF
执行的操作,标志寄存器低 8位 ← (SP)
标志寄存器高 8位 ← (SP)+1
(SP)←(SP)+ 2
PUSHF和 POPF指令用于保护和恢复标志寄
存器内容 。
(3)把标志寄存器推入栈顶指令 PUSHF
32
例如:
PUSH AX
PUSH CX
PUSHF ;保护标志寄存器内容;这段程序要用到 AX,CX以及标志位
POPF ;恢复标志寄存器内容
POP CX
POP AX
.,
.
33
数据传送指令中, 除 SAHF和 POPF这两条指令
外, 其余所有指令均不影响标志位 。
34
3.3.2 算术运算指令
涉及 两种类型数据, 无符号数和有符号数。
对加减法指令,无符号和有符号数可采用同
一套指令,但应注意:
?参加的操作数必须都是无符号数或都是有
符号数。
?需使用不同的标志位来检查无符号数和有
符号数的运算结果是否溢出。
35
? 两个 8位数相加时有 4种情况:
① 无符号数和有符号数均不溢出
二进制相加 无符号数加 有符号数加
0000 1000 8 +8
+0001 1110 + 30 + (+30)
0010 0110 38 +38
结果 38 CF=0 OF=0
36
② 无符号数溢出
0000 1000 8 +8
+1111 1101 +253 +(-3)
10000 0101 261 +5
结果 5 CF=1 OF=0
③ 有符号数溢出
0000 1000 8 +8
+0111 1101 +125 +( +125)
1000 0101 133 +133
结果 -123 CF=0 OF=1
( 补码表示 )
37
④ 无符号数和有符号数均溢出
1000 1000 136 -120
+1111 0111 +247 +( -9)
10111 1111 383 -129
结果 127 CF=1 OF=1
上面四种情况说明, CF标志可用来表示无符号数
的溢出, OF标志可用来表示有符号数的溢出 。
有符号数的溢出是一种 出错状态, 在运算过
程中应当避免 。
38
共有 5条,
(1) 不带进位的加法指令 ADD
格式,ADD acc,data
ADD mem/reg,data
ADD mem/reg1,mem/reg2
例,ADD AL,30H
ADD AX,[BX+20H]
ADD CX,SI
ADD [DI],200H
ADD指令对标志位 ( 指状态标志 ) 都有影响 。
1.加法指令
39
(2) 带进位位的加法指令 ADC
ADC指令在形式上和功能上都有与 ADD类
似,只是相加时还要包括进位标志 CF的内
容,例如:
ADC AL,68H ;AL←(AL)+68H+(CF)
ADC AX,CX ;AX←(AX)+(CX)+(CF)
ADC BX,[DI] ;BX←(BX)+[DI+ 1][DI]
+(CF)
40
例,有两个 4字节的无符号数相加:
2C56F8AC+309E47BE=?
设被加数、加数分别存放在 BUFFER1及
BUFFER2开始的两个存储区内,结果放回
BUFFER1存储区,如下页图所示。
因 CPU只能进行 8位或 16位的加法运算, 为
此可将加法分 4次进行 。
ADC指令主要用于多字节加法运算中
41
56H
2CH
BEH
47H
BUFFER1
BUFFER2
ACH
F8H
9EH
30H








多字节加法示意图
...
42
程序段如下:
MOV CX,4 ;置循环次数
MOV SI,0 ;置 SI初值为零
CLC ;清进位标志 CF
LL,MOV AL,BUFFER2[SI]
ADC BUFFER1[SI],AL ;带进位加
INC SI ;(SI)+1
DEC CX ;(CX)-1
JNZ LL ;若 (CX)?0,则转 LL
思考:若最高位有进位, 如何改?