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
思考:若最高位有进位,如何改?