第3章

8086/8088 
指令系
统


指令系统是微处理器的基本功能描述,是各种程序设计语言的基础。8086/8088 指令
系统是Intel80X86 系列微处理器的基本指令集,包括数据传送指令、算术运算指令、逻辑运
算指令和移位指令、控制转移指令和处理器控制指令。这些指令是汇编语言程序设计的
基础。

3.1 
概述
程序是人操纵驾驭计算机的工具,程序设计语言是编制程序的工具。程序设计语言主
要分为机器语言、汇编语言和高级语言。这些语言的使用环境不同,操纵计算机的方法不
同,各有优缺点。

3.1 
机器语言与汇编语言
1.
机器语言能被计算机硬件直接识别并执行,它由二进制代码组成。机器语言中的每一
条称为指令,计算机能够识别的所有指令的集合称为指令系统。指令是计算机能够执行的
最小功能单位,机器语言程序就是由一条条的指令按一定顺序组织起来的指令序列。计算
机的CPU 不同,指令系统也不同。Intel公司的80X86 系列CPU,因其硬件结构设计上的
包容性,指令系统具有兼容性,用8088/8086CPU 的指令系统设计的程序可以在80X86 系
列的CPU 上执行。8088/8086CPU 的指令系统常被称为80X86 系列CPU 的基础指令。
本章以8086CPU 为主,介绍常用计算机指令的格式、寻址方式和用法。

一条指令一般由操作码和操作数两部分组成。操作码详细地说明指令要执行的操作, 
操作数是指令执行时需要的数据。机器语言中操作码和操作数都是二进制代码,因而难于
记忆、书写和输入,即使对于计算机的设计者,也一样难于使用。因此,指令中的操作码和操
作数用便于记忆的符号代替,编程语言因而有了第一次发展,由机器语言进化到汇编语言。
符号化的操作码称为指令助记符,操作数称为操作数助记符。本章以汇编语言指令的形式, 
介绍8086CPU 指令集中常用的指令格式、寻址方式和用法。


第3 章 8086/8088 指令系统 43 
3.1.2 指令的基本构成
1.指令的一般格式 
一条指令包含操作码和操作数两部分。任何指令都含有操作码,操作数可以有一个,也
可以有两个,还可以没有。只有一个操作数的指令常称为单操作数指令,有两个操作数的指
令常称为双操作数指令。形式上无操作数的指令,通常操作数是隐含的。操作数有源操作
数和目的操作数之分。
如图3-1所示,8086CPU 指令由1~7字节组成。操作码占1~2 字节,操作数占
2~5字节。操作码的长度取决于指令系统的规模大小。操作数的长度与指令的寻址方式
有关。
图3-1 指令的基本组成
2.操作数类型
8086/8088CPU 的算术运算单元只能处理整数,不能处理小数,因此本章中所有指令
的操作数都是整数,没有小数。8086CPU 指令的操作数有三种类型:立即数操作数、寄存
器操作数和存储器操作数。
. 立即数操作数又称为常数,可以是数值型常数,也可以是字符型常数。数值型常数
可以是字节或字类型的整数,可以无符号或有符号。立即数在指令中只能作为源操
作数,不能作为目的操作数。例如: 
MOV AX, 2023H ;2023H 是字类型的无符号整数,AX=2023H 
MOV AX,-1423H ;-1423H 是字类型的带符号整数,AX=EBDDH(补码) 
MOV AH,'A' ;'A'是字符型常数,将'A'的ASCII 值41H 赋给AH 寄存器
MOV AL, 6 ;6 是数值型操作数,默认为十进制,指令执行后AL=6 
. 寄存器操作数,8086CPU 的8个16位的通用数据寄存器AX、BX、CX、DX、SP、BP、
SI、DI和4个段寄存器CS、DS、SS、ES可作为16位寄存器操作数,AH、BH、CH、
DH 和AL、BL、CL、DL可作为8位寄存器操作数。控制寄存器IP、Flags只在特定
指令中作为操作数。寄存器操作数在指令中可作为源操作数,也可作为目的操作
数,段寄存器CS除外,它只能作为源操作数。
. 存储器操作数,就是用内存单元中的数据作为操作数。存储器操作数既可以作为源
操作数,也可以作为目的操作数,但多数指令要求源和目的操作数不能同时为存储
器操作数。指令中的操作数如果是存储器操作数,指令中通常给出的是存储单元的
地址或用某种方式指明存储单元的地址,指令执行时CPU 根据这个地址从存储单
元中取出操作数,然后执行指令。存储器操作数的长度类型可以是1字节、2字节
(字)或者4字节(双字)。寄存器操作数和存储器操作数相对于立即数又称为变数。

44 微型计算机原理与接口技术(第2 版) 
数据在内存中以“高高低低”的原则存放,低字节存于低地址内存中,高字节存于高地址
内存中。存储器操作数如果是多字节,指令中指明的存储单元地址通常是它的低地址,或称
为首地址。如寄存器AX中的内容为6E53H,将它存入20000H 中,结果如图3-2所示。
图3-2 数据存放
3.指令的书写格式
指令的书写格式如下: 
标号:操作码助记符 目的操作数助记符,源操作数助记符;注释
例如:GOON: MOV AX,BX ;数据传送
. 标号是字母、数字组合的符号,代表指令,是指令的地址———用符号表示的地址。标
号后跟冒号“:”作为间隔符。不是每条指令都有标号,标号由程序员根据编程需要
设定。标号一般由字母开头的字母、数字组成,长度不超过31个字符。不允许使用
汇编语言中的保留字作标号。
. 操作码助记符与操作数助记符之间至少应有一个空格作为间隔符。如果指令有两
个操作数,操作数之间以逗号“,”作为间隔符。紧挨操作码助记符的操作数为目的
操作数,另一个为源操作数。
. 操作数助记符与注释之间用分号“;”作为间隔符。注释部分可有可无,可以跟在指
令的后面,也可以单独一行,若注释超过一行,则新行以分号“;”开头。简明扼要的
注释可以增加程序的可读性,汇编语言程序的可读性很差,应尽量多写注释。
. 指令中的标点符号应为ACSII字符。
3.2 寻址方式
8088/8086CPU 对内存采用分段管理,内存单元地址由段基址和段内偏移地址组成, 
段基址和段内偏移地址称为内存单元的逻辑地址。指令中存储器操作数的内存单元地址一
般给出的是段内偏移地址,段基址以默认方式指明。段内偏移地址,在多数时候指令也不是
直接给出,而是给出一种计算偏移地址的公式或方法。这么做的原因一方面是编程需要,如
循环程序每次循环处理不同的数据,数据的地址就应该以某种规律变化;另一方面,与数据
在内存中的存放形式有关,如一维数组、二维数据等。当然,也与程序员的个人编程习惯有
关。实际上,寻址方式就是CPU 为方便编程而设置的存取存储器操作数的方式方法。
寻址方式,即获得地址的方法,主要指获得段内偏移地址的方法,段基址常采用默认方

第3 章 8086/8088 指令系统 45 
式获得。指令的操作数有三种类型:立即数、寄存器操作数和存储器操作数。立即数作为
指令的一部分出现在指令中,随着CPU 取指令的动作进入CPU 内,不需要再寻址;寄存器
操作数本就在CPU 内部,寄存器的符号就是地址;所以,寻址方式主要解决的是存储器操
作数的段内偏移地址的获得方法。操作数的段基址由相应的段寄存器DS、ES或SS提供, 
指令中以默认的方式表达。立即数、寄存器操作数,它们不需要寻址,但是,为了理论的统一
性,也给它们命名了寻址方式。下面分别介绍8086CPU 指令中操作数的寻址方式,共有
8种。
3.2.1 立即寻址
操作数是立即数,例如: 
MOV AL, 76 ;把十进制数76 传送给AL,字节(8 位)数据传送
MOV AX, 2000H ;把2000H 传送给AX,字(16 位)传送
MOV BX, 34H ;把0034H 传送给BX,字(16 位)传送
MOV SI, 0 ;把0000H 传送给SI,字(16 位)传送
MOV AH, 'A' ;把A 的ASCII 41H 传送给AH,字节传送
MOV AX, 'BA' ;把BA 的ASCII 传送给AX,AX=4241H,字传送
MOV CL, 10010010B ;把二进制数10010010 传送给CL,字节传送
ADD AL, 6 ;寄存器AL+6,结果回送到AL 中
立即数作为操作数,这个操作数的寻址方式称为立即寻址,其实它不用寻址。立即数操
作数只能作源操作数,不能作目的操作数。立即数可以以十进制形式书写,而且默认是十进
制,书写时不用加后缀。立即数如果是十六进制,则需要加后缀H,而且如果是字母开头的
十六进制数,汇编语言要求前面加0,如MOV BX,0FE60H 。立即数如果是二进制形式, 
则后缀要加B。
3.2.2 直接寻址
直接寻址是存取存储器操作数的方法之一。数据段内存储单元中的数据作为操作数, 
指令中直接给出操作数所在的内存单元的偏移地址。偏移地址可以是数值形式的地址,也
可以是用符号表示的地址,用符号表示的地址称为符号地址。例如,内存单元偏移地址
2000H 中存有数据55H,在指令中这个操作数的形式为[2000H],符号[]表示地址。例如: 
MOV BL, [2000H] ;将偏移地址为2000H 的存储单元中的数据传送给BL 
MOV BX, [3200H] ;将偏移地址3200H 的连续两个存储单元中的数据传送给BX 
MOV AL, BUFF ;将数据段中BUFF 单元存储的数据传送给AL 
MOV AX, STR ;将数据段中STR 和STR+1 单元存储的数据传送给AX 
MOV THERE, BX ;将BX 中的数据传送给以THERE 开始的连续两个单元中
操作数[2000H]的寻址方式为直接寻址,如果2000H 单元存储的数据为55H,MOV 
BL,[2000H]指令执行后BL=55H。 
MOV BX, [3200H]

46 微型计算机原理与接口技术(第2 版) 
指令中操作数[3200H]的寻址方式为直接寻址。将以偏移地址3200H 为首地址的连
图3-3 直接寻址
续两个内存单元的内容传送给BX 寄存器。如图3-3所示,3200H 
单元存储的数据为F8H,传送给BL寄存器,3201H 单元存储的数据
为03H,传送给BH 寄存器。上面指令执行后BX=03F8H。
注意:BX为16位的寄存器,决定了这条指令为16位的数据传
送指令。
上面指令示例中的BUFF、STR、THERE都是存储单元的偏移
地址,也称为符号地址,它们应该在程序开始处予以定义,否则不能
使用。它们的寻址方式为直接寻址,可以书写为 
MOV AL, [BUFF] ;将BUFF 存储单元中的数据传送给AL 
MOV AX, [STR] ;STR、STR+1 存储单元的数据分别传送给AL、AH 
MOV [THERE], BX ;BL、BH 中的数据分别传送给存储单元THERE、THERE+1 
更常见的写法为 
MOV AL, BUFF 
MOV AX, STR 
MOV THERE, BX 
8088/8086CPU 对内存采用分段管理,汇编指令中存储器操作数的地址包括段基址和
段内偏移地址两部分。上面指令中的[2000H]、[3200H]、BUFF、STR、THERE,都是段内
偏移地址,它们的段基址由DS指明。通常情况下,存储器操作数默认在数据段,段基址在
DS。在特殊说明的情况下,存储器操作数的段基址也可以替换为CS、ES或SS。表3-1说
明了8088/8086CPU 系统中逻辑地址的来源。
表3-1 8088/8086CPU 系统中逻辑地址的来源
操作类型默 认 段可替换的段偏移地址
取指令CS 无IP 
堆栈操作SS 无SP 
BP作基地址SS CS,DS,ES 由寻址方式决定
BX作基地址DS CS,ES,SS 由寻址方式决定
一般数据读/写DS CS,ES,SS 由寻址方式决定
串操作中的源串DS CS,ES,SS SI 
串操作中的目的串ES 无DI 
CPU 执行指令时,在BIU 中按照段基址x10H+段内偏移地址的方法,计算产生20位
的物理地址并送到地址总线上,然后BIU 对选中的存储单元进行数据存取。例如: 
MOV BL, [2000H] 
设DS=1200H,指令在执行过程中,首先BIU 在地址加法器中进行计算: 
1200H×10H+2000H=14000H

第3 章 8086/8088 指令系统 47 
然后从14000H 内存单元取出55H 传送给BL寄存器。
如果操作数的段基址不是DS段,指令要特别说明。例如,在ES段,指令应书写为 
MOV BL, ES:[2000H] 
这种用法称为段超越,“:”为段超越符,物理地址的计算方法为ES×10H+2000H。
3.2.3 寄存器寻址
操作数在CPU 内部的寄存器中,即寄存器操作数。8086/8088CPU 的8个16位的通
用数据寄存器AX、BX、CX、DX、SP、BP、SI、DI和4个段寄存器CS、DS、SS、ES可以作为16 
位寄存器操作数,AH、BH、CH、DH 和AL、BL、CL、DL可以作为8位寄存器操作数。寄存
器操作数在指令中可以作为源操作数也可以作为目的操作数,通常源和目的操作数的长度
应该保持一致,可以都是字节类型,也可以都是字类型。下面示例中源和目的操作数的寻址
方式都是寄存器寻址。 
MOV AL, BL ;把BL 的内容复制到AL 中,字节传送
MOV AH, BH ;把BH 的内容复制到AH 中,字节传送
MOV CH, CL ;把CL 的内容复制到CH 中,字节传送
MOV BH, AL ;把AL 的内容复制到BH 中,字节传送
MOV AX, BX ;把BX 的内容复制到AX 中,字传送
MOV DX, CX ;把CX 的内容复制到DX 中,字传送
MOV SP, BP ;把BP 的内容复制到SP 中,字传送
MOV SI, DI ;把DI 的内容复制到SI 中,字传送
MOV DI, AX ;把AX 的内容复制到DI 中,字传送
MOV BX, ES ;把ES 的内容复制到BX 中,字传送
ADD AX, BX ;AX+BX 结果保存在AX 中,16 位加法运算
3.2.4 寄存器间接寻址
寄存器间接寻址可以表示任何存储单元的数据。内存单元的偏移地址存放在寄存器
中,可以是SI、DI、SP、BX寄存器中的任何一个,但不能是其他寄存器。例如,如果偏移地址
为0100H 的内存单元中的数据作为操作数,而且这个地址已经存储在SI寄存器中(SI= 
0100H),指令中我们可以使用[SI]形式表示这个操作数,[]表示这是地址。 
MOV AL, [SI] ; 将[SI]表示的存储单元中的数据传送给AL 
操作数[SI]的寻址方式为寄存器间接寻址。上述指令的功能为:SI的内容为内存单元
的偏移地址,DS为段基址(默认),指令执行时CPU 中的BIU 按照公式DS×10H+SI计算
出存储单元的物理地址并送到地址总线上。参照图3-4,如果DS=2000H,则DS×10H+ 
SI=2000H×10H+0100H=20100H,BIU 从物理地址为20100H 的内存单元中取出数据
53H 送给EU,EU 将53H 传送给AL,指令执行结束。

48 微型计算机原理与接口技术(第2 版) 
图3.4 段中的数据 
注意,[SI]表示存储区域的首地址。因此[SI]可以表示一个内存单元,也可以表示2个
连续的内存单元,甚至是4个连续的内存单元。这一点与直接寻址[1000H]的用法一致。
再如: 
MOV AX, [SI] ;将DS:[SI]指明的连续两个内存单元中的数据传送到AX 
MOV DX, [DI] ;将DS:[DI]指明的连续两个内存单元中的数据传送到DX 
MOV [BX], AX ;AX 的内容传送到DS:[BX]指明的连续两个内存单元中
MOV CX, [BP] ;将SS:[BP]指明的连续两个内存单元中的数据传送到CX 
操作数[SI]、[DI]、[BX]、[BP]的寻址方式都是寄存器间接寻址。8086CPU 中能作为
寄存器间接寻址方式使用的寄存器只有4个:BX、BP、SI、DI。这4个寄存器作为间接寻址
使用时,要用[]申明,这时常称它们为地址指针寄存器或间址寄存器。BP作为间址寄存器
时,段基址默认为SS,其他3个的默认段基址为DS,但都可以段超越。例如: 
MOV DX, ES:[DI] ;将ES:[DI]指明的连续两个内存单元中的数据传送到DX 
如果ES=3000H,DI=0102H,则ES×10H+DI=3000H×10H+0102H=30102H,上述指
令的具体功能为:以30102H 为首地址,从内存中取出连续两个内存单元中的数据传送给
DX,指令执行的结果为:DX=C396H。
如果某种情况下要求间接寻址操作数必须具有确定的数据长度,要求汇编语言在其前
边增加属性操作符PTR,例如,指令MOV [SI],4中的两个操作数的长度都不是确定的, 
CPU 执行指令时是进行字节传送,还是字传送? 存在不确定性,这时需要使用BYTE 
PTR、WORDPTR、DWORDPTR这几种伪指令操作符去限定数据类型。例如: 
MOV BYTE PTR[SI], 4 ;将04H 赋值给SI 表示的内存单元
MOV WORD PTR[DI], 4 ;将0004H 赋值给以DI 为首地址的连续两个内存单元
MOV AL, 4 ;将4 赋值给AL,字节传送,因为AL 具有确定的数据长度
3.2.5 寄存器相对寻址
寄存器相对寻址是定位存储器操作数的另一种方法,是在寄存器间接寻址的基础上,存
取跟它有一定距离(位移量)的内存单元中的数据所使用的寻址方式。例如,存取数据表中
的数据,可以用间址寄存器存放数据表首地址,用位移量指明要存取表中的哪一个数据。寄
存器相对寻址表示的内存单元,它的偏移地址由两部分组成:一部分由间接寻址寄存器提

第3 章 8086/8088 指令系统 49 
供;另一部分是指令给定的8位或16位的地址位移量。二者相加形成操作数的有效地址。
例如: 
MOV AX, [BX+DATA] ;将以BX+DATA 为首地址的连续两个内存单元中的数据
;传送给AX 
MOV AL, [SI+20H] ;将以SI+20H 为地址的内存单元中的数据传送给AL 
MOV CX, [DI+DATA] ;将以DI+DATA 为首地址的连续两个内存单元中的数据传送给CX 
MOV DX, [BP+DATA] ;将堆栈段中以BP+DATA 为首地址的连续两个内存单元中的数据 
;传送给DX 
上述指令的书写格式很灵活,也可以书写成如下形式: 
MOV AX, [BX]+DATA 
MOV AL, 20H [SI] 
MOV CX, DATA [DI] 
MOV DX, DATA+[BP] 
寄存器相对寻址方式对寄存器的要求与寄存器间接寻址一样,只有4个寄存器:BX、
BP、SI、DI可以使用,并且要用[]申明。BP在寄存器相对寻址时,段基址默认为SS,其他3 
种情况,段基址默认为DS。
3.2.6 基址变址寻址
基址变址寻址也是以寄存器间接寻址为基础,寻址数组中的数据。它由一个基址寄存
器(BX或BP)加上一个变址寄存器(SI或DI),作为操作数的偏移地址。例如: 
MOV AX, [BX][SI] ;将以BX+SI 为首地址的连续两个内存单元中的数据送给AX 
MOV CX, [BP][DI] ;将以BP+DI 为首地址的连续两个内存单元中的数据送给CX 
MOV [BX][DI], AL ;将AL 中的数据存入BX+DI 表示的内存单元中
MOV [BP][SI], DX ;将DX 中的数据存入以BP+SI 为首地址的连续两个内存单元中
8086CPU 中,寄存器BX和BP为基址寄存器,SI和DI为变址寄存器。这种寻址方式
中,一个基址寄存器加一个变址寄存器构成操作数,操作数的形式只有4种: 
[BX][SI] 
[BX][DI] 
[BP][SI] 
[BP][DI] 
这种寻址方式的段基址是DS还是SS呢? 8086汇编规定以基址为主,如果基址寄存器
为BP,则操作数的段基址默认由SS提供;若BX为基址寄存器,则段基址默认由DS提供。
例如: 
MOV AX, [BX][DI] ;源操作数的物理地址为DS×10H+BX+DI 
MOV [BP][DI], DX ;目的操作数的物理地址为SS×10H+BP+DI 
基址变址寻址方式要求必须一个基址和一个变址组合,不允许两个基址或两个变址组
合。下面指令是错误的。

50 微型计算机原理与接口技术(第2 版) 
MOV AX, [BX][BP] 
基址变址寻址可以寻址存储器数组中的任何元素。将数组的首地址装入基址寄存器,将
要存取元素的序号存入变址寄存器,通过修改变址寄存器中的内容访问数组中的各个元素。
3.2.7 基址变址相对寻址
基址变址相对寻址是在基址变址寻址的基础上增加一个位移量,这种寻址方式常常用
来寻址存储器中的二维数组。操作数的地址由基址寄存器加上变址寄存器再加上地址位移
量构成。如果基址寄存器为BP,则段基址默认由SS提供;若基址寄存器为BX,则段基址默
认由DS提供。例如: 
MOV AX, BUFF[BX][SI] ;将BUFF+BX+SI 作为偏移地址的连续两个内存单元 
;的数据传送给AX 
MOV STRING[BX][DI], DX ;将DX 的内容传送到以STRING+BX+DI 为偏移地址的 
;连续两个内存单元
MOV CX, [BP+DI+20H] ;将BP+DI+20H 作为偏移地址的连续两个内存单元的 
;数据传送给CX 
MOV FILE[BP][SI], AL ;将AL 的内容传送到以FILE+BP+SI 为偏移地址的内存 
;单元
指令也可以书写为 
MOV AX, [BUFF+BX+SI] 
MOV [STRING+BX+DI], DX 
MOV [FILE+BP+SI], AL 
基址变址相对寻址方式要求必须一个基址和一个变址组合,不允许两个基址或两个变
址组合。
这种寻址方式主要用于寻址二维数组中的数据。如果程序中定义了4行10列的二维
数组FILE,FILE作为数组首地址,基址寄存器BX寻址行,变址寄存器SI寻址列,则可以
很方便地实现数据阵列检索。
3.2.8 隐含寻址
操作码隐含地指明操作数,例如乘法指令、字符串操作指令。 
MUL BL ;AL 乘以BL,结果存在AX 中,隐含乘数AL 和乘积AX 
MOVSB ;把DS:SI 指明的内存单元的数据传送到ES:DI 指明的内存单元
3.3 8086CPU 指令系统
8088CPU 和8086CPU 的指令系统完全相同,共有133条基本指令,本节将这些指令

第3 章 8086/8088 指令系统 51 
分为6个功能组进行介绍。
. 数据传送指令
. 算术运算指令
. 逻辑运算与移位指令
. 串操作指令
. 程序控制指令
. 处理器控制指令
汇编语言的基本语法规则及基本概念,如变量、标号、表达式及运算符等,将在介绍指令
的过程中讲解,不单独讲解。在介绍具体指令之前,先介绍一些符号约定: 
OPRD 各种类型的操作数
src 源操作数
dst 目的操作数
acc 累加器AX 或AL 
port 输入/输出端口
count 计数器
3.3.1 数据传送指令
数据传送指令是汇编语言中使用最频繁的指令,通常细分为通用数据传送指令、输入/输
出指令、地址传送指令和标志寄存器传送指令。
1.通用数据传送指令MOV,PUSH,POP,XCHG,XLAT 
1)MOV 
指令格式: 
MOV dst,src 
功能:数据传送,把src的内容传送到dst中。
说明:把源操作数复制到目标操作数中,它可以实现: 
(1)立即数到通用寄存器的数据传送。
例如: 
MOV AL,4 ;AL=4 
MOV AX,1000H ;AX=1000H 
MOV SI,037BH ;SI=037BH 
但是 
MOV DS,2000H ;语法错误,不能用立即数给段寄存器赋值
应该为 
MOV AX,2000 
MOV DS,AX

52 微型计算机原理与接口技术(第2 版) 
(2)立即数到存储单元的数据传送。
例如: 
MOV WORD PTR[DI], 2000H 
图3-5 数据传送
将立即数2000H 传送到内存单元,内存单元的地址以间接寻址
的方式由DI提供。设DS=3000H,DI=1500H,目的操作数的物理
首地址为31500H,指令执行后如图3-5所示。
PTR是属性运算符,功能为修改操作数的类型。WORDPTR 
的作用是将操作数的类型设置为字类型,BYTEPTR的作用是将操
作数的类型设置为字节类型。例如: 
MOV BYTE PTR[SI], 4AH 
将立即数4AH 传送到内存单元,内存单元的地址以间接寻址的方式由SI提供,传送一
字节。 
MOV [DI],04AH ;语法错误: 源和目的操作数的类型都不确定
这条指令不可用,因为源和目的操作数的类型都不确定,指令执行结果也不确定,这种
情况称为二异性。指令执行时可能传送一字节,将立即数4AH 传送给[DI]指明的内存单
元,也可能传送两字节,4A 赋给内存单元[DI],0赋给内存单元[DI+1]。
MOV 指令中的两个操作数的类型必须至少有一个是确定的,另一个依附这一个。属
性运算符PTR帮助确定存储器操作数的类型。
(3)CPU 内部寄存器之间的数据传送。
例如: 
MOV AL,BL ;BL 传送给AL,传送一字节
MOV AX,BX ;BX 传送给AX,传送一个字
MOV DS,AX ;给数据段寄存器赋值
MOV SI,BP ;BP 传送给SI,传送一个字
(4)寄存器与存储单元之间的数据传送。
例如: 
MOV AL,[2000H] ;将2000H 单元的内容传送给AL,传送一字节
MOV AX,[SI] ;将以SI 为首地址的连续两个内存单元中的数据传送给AX 
MOV [3200H], CX ;将CL 存入3200H 单元,将CH 存入3201H 单元
MOV ARRY[DI], DL ;将DL 的内容存入ARRY+DI 的内存单元中
MOV DL,[BX][SI] ;将BX+SI 内存单元中的数据传送给DL 
(5)存储单元之间的数据传送。
不能用一条MOV 指令实现内存单元之间的数据传送。8086汇编语法规定MOV 指
令中两个操作数不能同时为存储器操作数。要实现存储单元之间的数据传送,需要两条指
令。例如: 
MOV [DI], [SI] ;语法错误

第3 章 8086/8088 指令系统 53 
应该为 
MOV AX,[SI] 
MOV [DI], AX 
使用MOV 指令时注意: 
(1)MOV 指令不影响标志寄存器的任何标志位。
(2)源和目的操作数不可同时为存储器操作数。
(3)源和目的操作数必须等长,即同时为字节类型或字类型。
(4)不能用立即数给段寄存器赋值。
(5)不允许给CS赋值。
(6)MOV 指令不能访问IP和FLAGS。
2)PUSH,POP 
PUSH 和POP是堆栈操作指令助记符。堆栈是程序在内存中开辟的一个数据存储
区,用于保存函数调用或者中断处理过程中的程序返回地址,或者是程序暂时不用而又必须
保存的数据。程序中,堆栈是用段定义语句在内存中定义的一个段,段基址存放在SS寄存
器,段内偏移地址存放在SP寄存器。堆栈段的起始单元称为栈底,堆栈指针SP常称为
栈顶。堆
栈是一种线性表,只在栈顶一端进行数据输入/输出操作。堆栈操作采用先进后出
(或后进先出)的存取方法。数据存入堆栈称为压入堆栈,使用PUSH 指令。从堆栈中取出
数据称为弹出堆栈,使用POP指令。程序中,堆栈初始化时,堆栈段起始物理地址为SS* 
10H,段的最大长度为FFFFH,堆栈段的末地址最大为SS*10H+FFFFH,堆栈指针默认
图3-6 堆栈段
SP=0。假设SS=2000H,堆栈段如图3-6所示。
堆栈指令的操作数必须是16位的字类型操作数。所以, 
PUSH 指令执行时,首先将操作数的高字节数据存入SP-1单
元中,低字节数据存入SP-2单元中,然后执行SP-2修改堆栈
指针。SP总是指向堆栈中最上层包含数据的存储单元,它称
为栈顶。如果连续向堆栈中压入数据,SP的值越来越小,代
表堆栈中可用的存储区域越来越少,栈顶向堆栈段的起始单
元方向移动。
图3-6中,第一次向堆栈压入数据时,SP=0000H,假设
DX=C56EH,执行PUSHDX指令,高字节C5H 存入SP-1= 
FFFFH 单元中,低字节6EH 存入SP-2= FFFEH 单元中。
然后执行操作SP-2=SP,即0000H-2=FFFEH。堆栈段
起始单元物理地址为20000H,第一次压入的数据存储在堆栈段的末端,物理地址为
2FFFEH 和2FFFFH 单元,堆栈指针SP=FFFEH。
从堆栈中弹出数据时,首先弹出SP中的数据(16位数据中的低8位),然后弹出SP+1 
中的数据(16位数据中的高8位),接下来执行SP+2调整指针。数据的弹出过程与压入过
程相反,堆栈指针SP增大,向堆栈段的末端方向移动。
指令格式:

54 微型计算机原理与接口技术(第2 版) 
PUSH src ;压栈指令
POP dst ;出栈指令
PUSH 指令把操作数压入堆栈,执行过程为
(1)src的高8位存入[SP-1],src的低8位存入[SP-2]; 
(2)SP-2送SP。
例如: 
设SS=2000H,SP=102H,AX=623EH,执行下面的指令后: 
PUSH AX 
AX的数据62H 存入20101H 单元,3EH 存入20100H 单元,SP=0100H。
POP指令把操作数弹出到dst中,执行过程为
(1)把[SP]的内容弹出到dst的低8位,把[SP+1]的内容弹出到dst的高8位; 
(2)SP+2送SP。
例如:设SS=2000H,SP=100H,执行下面的指令后: 
POP BX 
堆栈中20100H 单元的数据传送给BL,20101H 单元的数据传送给BH,BX=623EH, 
SP=102H。
堆栈操作指令属于单操作数指令,操作数可以是寄存器,也可以是存储器。堆栈指令的
操作数必须是字类型,可以是16位的通用寄存器或段寄存器,也可以是两个连续的内存单
元,可以采用任何寻址方式。8086CPU 不允许立即数作为堆栈操作的操作数,CS不能作为
出栈指令的操作数。堆栈指令不影响任何标志位。
例如: 
PUSH DI ;将DI 中的数据压入堆栈
PUSH SI ;将SI 中的数据压入堆栈
PUSH DX ;将DX 中的数据压入堆栈
PUSH DS ;将DS 中的数据压入堆栈
PUSH CS ;将CS 中的数据压入堆栈
PUSH WORD PTR[1000H] ;将以1000H 单元开始的连续两个单元的内容压入堆栈
PUSH WORD PTR[SI] ;将以[SI]单元开始的连续两个单元的内容压入堆栈
PUSH WORD PTR[BP+6] ;将以[BP+6]单元开始的连续两个单元的内容压入堆栈
POP DI ;从栈顶中弹出两个单元的数据送给DI 
POP SI ;从栈顶中弹出两个单元的数据送给SI 
POP DX ;从栈顶中弹出两个单元的数据送给DX 
POP DS ;从栈顶中弹出两个单元的数据送给DS 
POP WORD PTR[1000H] ;将SP 单元的数据弹出送给1000H 单元,SP+1 单 
;元的数据弹出送给1001H 单元
POP WORD PTR[SI] ;将SP 单元的数据弹出送给[SI]单元,SP+1 单元的 
;数据弹出送给[SI+1]单元
POP WORD PTR[BX+DI] ;将SP 单元的数据弹出送给[BX+DI]单元,SP+1 单 
;元的数据弹出送给[BX+DI+1]单元

第3 章 8086/8088 指令系统 55 
注意:程序中,压栈操作和出栈操作通常成对出现,以保持堆栈的平衡。
3)交换指令XCHG 
指令格式:XCHG OPRD1,OPRD2 
功能:两个操作数交换。
说明:操作数可以是通用寄存器,不能是段寄存器;可以是存储器单元,但两个操作数
不能同时为存储器操作数。两个操作数的字长必须相等。
例如: 
XCHG AX, BX 
XCHG AL, [SI] 
XCHG [BX+DI], CX 
4)字节转换指令XLAT 
XLAT主要用于查表转换和隐含寻址。该指令的功能是将内存单元[BX+AL]的单字
节内容传送给AL寄存器,指令执行前后AL的内容发生转换。使用XLAT 指令前,需要
预置DS:BX指向一张表,BX作为表的首地址。如果查表中第9字节的内容,需要预置AL 
为9。
指令格式:XLAT 
【例3-1】 DS数据段中存放有7段LED显示器表,如图3-7所示。TABLE为表首地
图3-7 码值表
址,查表取出LED显示器数字3的显示字型码。 
MOV BX, OFFSET TABLE 
MOV AL, 3 
XLAT ;AL=4FH 
OUT 88H, AL ;LED 显示数字3 
2.输入/输出指令IN/OUT 
8086CPU 对所有输入/输出端口统一管理,提供了一个与
内存储器地址空间分开的、完全独立的地址空间,I/O 端口的
地址有8位和16位两种形式。8086CPU 对I/O 端口的管理
与对内存储器的管理不同,输入/输出指令中操作数的寻址方式也不同,是输入/输出指令特
有的。.
直接端口寻址方式:当端口地址是8位的二进制数时,可以在指令中直接使用该
地址。
. 寄存器间接寻址方式:当端口地址为16位时,不能直接使用,需要预先将其传送到
DX寄存器中,并且只能是DX作为间接寻址寄存器。
8086CPU 无论从端口输出数据还是输入数据,都要通过累加器AL或AX,所以输入/ 
输出指令又称为累加器专用传送指令。
1)输入指令IN 
格式: 
IN ACC, port ;直接寻址,8 位port 为立即数端口地址

56 微型计算机原理与接口技术(第2 版) 
或 
IN AC C, D X ;间接寻址,DX 存有16 位端口地址
例如: 
IN AL , 60 H ;从60H 端口输入一字节
IN AX, 90H ;从90H 端口输入一个字
IN AL, DX ;从DX 端口输入一字节
IN AX, DX ;从DX 端口输入一个字
2)输出指令OUT 
格式: 
OU T p or t, A CC ;直接寻址,port 为8 位立即数端口地址
或 
OU T D X, AC C ;间接寻址,DX 存有16 位端口地址
例如: 
OU T 6 0H , AL ;AL 从60H 端口输出
OUT 90H, AX ;AX 从90H 端口输出
OUT DX, AL ;AL 从DX 端口输出
OUT DX, AX ;AX 从DX 端口输出
【例3-2】 从并行口0378H 输出一个字符'A'。 
MO V D X, 03 78 H 
MOV AL,'A' 
OUT DX,AL 
3.地址传送指令LEA,LDS,LES 
地址传送指令共3条。
1)取有效地址指令LEA 
指令格式:LEA dst,src 
功能:把源操作数的地址偏移量传送到目标操作数。
说明:源操作数必须是存储器操作数,目标操作数必须是16位寄存器。
例如: 
LE A B X, T AB LE ;TABLE 的偏移地址传送给BX,TABLE 为符号变量
LEA SI, DATA[BX] ;SI=BX+DATA 
设BUFF为符号变量,比较下面两条指令的功能: 
MO V D I, O FF SE T BU F F 
LEA DI, BUFF

第3 章 8086/8088 指令系统 57 
上面两条指令的功能完全相同,但LEA 指令更简洁。OFFSET 为取值运算符,又称为
数值返回运算符,用于求变量或标号的属性值。常见的取值运算符还有SEG。
. SEG运算符用于求变量或标号所在段的段基址。例如: 
MO V A X, S EG B UF F ;BUFF 的段基址送AX 
. OFFSET用于求变量或标号的偏移地址。例如: 
MO V A X, O FF SE T BU F F ;BUFF 的偏移地址送AX 
2)取地址指针指令LDS 
指令格式:LDS dst, src 
功能:将段基址传送给DS寄存器,偏移地址传送给16位的地址指针寄存器。
说明:双字操作。从源操作数中连续取出4字节。
例如: 
LD S B X, ES : [1 00 0 H] 
图3-8 LDS指令
设从ES:[1000H]单元起顺序存放4字节,如图3-8所示,上面
指令的执行将0378H 作为偏移量传送给BX,将2000H 作为段基址传
送给DS。
3)取地址指针指令LES 
与LDS指令功能相似,只是段基址装入ES,而不是DS。例如: 
LE S S I, [1 00 0 H] 
4.标志寄存器传送指令LAHF,SAHF,PUSHF,POPF 
这4条指令都是隐含寻址方式。
1)LAHF指令
指令格式:LAHF 
功能:把标志寄存器FLAGS的低8位装入AH 寄存器。
2)SAHF指令
指令格式:SAHF 
功能:把AH 传送到FLAGS的低8位,指令影响标志位。
3)PUSHF指令
指令格式:PUSHF 
功能:把FLAGS压入堆栈。
4)POPF指令
指令格式:POPF 
功能:从堆栈中弹出两字节传送给FLAGS,指令影响标志位。

58 微型计算机原理与接口技术(第2 版) 
3.3.2 算术运算指令
8088/8086CPU 提供了加、减、乘、除4种基本算术运算指令,可以实现二进制数的运
算,也可以实现十进制数的运算,可以实现字节运算,也可以实现字运算,可以进行有符号数
运算,也可以进行无符号数运算,有符号数运算以补码形式进行。这4种算术运算指令都对
标志位产生影响。算术运算指令应尽量使用累加器作操作数。
1.加法运算指令和调整指令ADD,ADC,INC,AAA,DAA 
1)不带进位的加法运算指令ADD 
ADD指令完成两个操作数相加,并将结果保存在目的操作数中。
指令格式:ADD OPRD1, OPRD2 
功能:操作数OPRD1与OPRD2相加,结果保存在OPRD1中。
说明:操作数OPRD1可以是累加器AL或AX,也可以是其他通用寄存器或存储器操
作数,OPRD2可以是累加器、其他通用寄存器或存储器操作数,还可以是立即数。OPRD1 
和OPRD2不能同时为存储器操作数,不能为段寄存器。ADD指令的执行对6个状态标志
位都产生影响。
例如: 
AD D A L, B L ;AL+BL 结果存回AL 中
ADD AX, SI ;AX+SI 结果存回AX 中
ADD BX, 3DFH ;BX+03DFH 结果存回BX 中
ADD DX, DATA[BP+SI] ;DX 与内存单元相加,结果存回DX 中
ADD BYTE PTR[DI], 30H ;内存单元与30H 相加,结果存回内存单元中
ADD [BX], AX ;内存单元[BX]与AX 相加,结果存回[BX]中
ADD [BX+SI], AL ;内存单元与AL 相加,结果存回内存单元中
【例3-3】 求D9H 与6EH 的和,并注明受影响的标志位状态。 
MO V A L, 0 D9 H 
MOV BL, 6EH 
ADD AL, BL 
11011001 
+ 01101110 
`10``1`00`0111 
结果AL=47H,标志位CF=1,PF=1,AF=1,ZF=0,SF=0,OF=0。
2)带进位的加法运算指令ADC 
ADC指令主要用于多字节数的加法运算,以保证低位向高位的进位被正确接收。ADC 
指令完成两个操作数相加之后,再加上Flags的进位标志CF的值,CF的值可能为1或0。
指令格式: 
ADC OPRD1, OPRD2 
功能:操作数OPRD1与OPRD2相加后,再加上CF的值,结果保存在OPRD1中。
说明:对操作数的要求与ADD指令一样。
例如:

第3 章 8086/8088 指令系统 59 
AD C A L, B L ; AL + BL+CF 结果存回AL 
ADC AX, BX ;AX+BX+CF 结果存回AX 
ADC [DI], 30H ;[DI]+30H+CF 结果存回[DI]单元中
【例3-4】 求E583AD9FH 与C725BC6EH 的和,结果存放在DX:AX中。 
MO V A X, 0 AD 9F H ; A X= AD9FH 
MOV BX, 0BC6EH ;BX=BC6EH 
ADD AX, BX ;AX=6A0DH,CF=1 
MOV DX, 0E583H 
MOV BX, 0C725H 
ADC DX, BX ;DX=ACA9H,DX:AX=ACA96A0DH,CF=1 
在多字节数的加法运算中,首先进行低位数相加,再进行高位数相加。最低位相加可以
用ADD指令,是因为不需要加进位CF。高位数相加需要使用ADC指令,如果低位的加法
运算使CF=1,说明刚才的加法运算有进位,这个进位必须送到高位数中,否则运算结果是
错误的。
3)加1指令INC 
加1指令INC又称增量指令,该指令不影响CF标志位。
指令格式:INC OPRD 
功能:OPRD加1后送回OPRD。
说明:操作数OPRD可以是寄存器或存储器操作数,指令可以完成字节或字的加1 
操作。例
如: 
IN C A L 
INC AX 
INC BYTE PTR[SI] 
INC WORD PTR[BX+DI] 
4)十进制数加法调整指令AAA、DAA 
ADD和ADC指令允许BCD数作为操作数进行加法运算,按照十进制数的方式完成加
法运算。但是,CPU 在完成运算时依然按照二进制数进行,所以在ADD或ADC指令之后, 
应进行十进制的调整。
. 指令格式:AAA 
功能:将AL中的数进行十进制调整,结果保存在AX中。
说明:之前的加法指令必须是两个非压缩BCD 码相加,结果在AL中。AAA 指令隐
含操作数AL和AH。指令执行时: 
(1)若AL的低4位值大于9或辅助进位AF=1,则将AL加6,将AH 加1,并将AF 
和CF标志位均置1。
(2)AL高4位清0。
. 指令格式:DAA 
功能:将AL中的数进行十进制调整,结果保存在AX中。
说明:之前的加法指令必须是两个压缩BCD 码相加,结果在AL中。AAA 指令隐含

60 微型计算机原理与接口技术(第2 版) 
操作数AL和AH。指令执行时: 
① 若AL的低4位值大于9或辅助进位AF=1,则将AL加6,AF置1。
② 若AL的值大于9FH 或进位CF=1,则将AL加60H,CF置1。
2.减法运算指令SUB,SBB,DEC,NEG,CMP,AAS,DAS 
1)不带借位CF的减法指令SUB 
指令格式:SUB OPRD1,OPRD2 
功能:操作数OPRD1减去OPRD2,结果保存在OPRD1中。
说明:操作数OPRD1可以是累加器AL或AX,也可以是其他通用寄存器或存储器操
作数,OPRD2可以是累加器、其他通用寄存器或存储器操作数,还可以是立即数。OPRD1 
和OPRD2不能同时为存储器操作数,不能为段寄存器。SUB指令的执行对6个状态标志
位都产生影响。
例如: 
SU B A L, B L ;AL-BL,结果存回AL 
SUB CX, BX ;CX-BX,结果存回CX 
SUB DX, [SI] ;DX 与[SI]内存单元相减,结果存回DX 
SUB DATA[BX], CL ;内存单元的数减去CL,结果存回内存单元
SUB BL, 2 ;BL-2,结果在BL 中
SUB WORD PTR[BP+SI],100H ;内存单元减去100H,结果存回内存
【例3-5】 D9H 与6EH 相减,并注明受影响的标志位状态。 
MO V AL , 0D 9H 
MOV BL, 6EH 
SUB AL, BL 
11011001 
- 01101110 
01101011 
`` ``` 
结果AL=6BH,标志位CF=0,PF=0,AF=1,ZF=0,SF=0,OF=1。
2)带借位CF的减法指令SBB 
指令格式:SBB OPRD1, OPRD2 
功能:操作数OPRD1减去OPRD2再减去CF的值,结果保存在OPRD1中。
说明:与SUB指令相同,常用于多字节数减法,对6个状态标志位都产生影响。
例如: 
SB B A L, 3 0H ;AL-30H-CF,结果存回AL 
SBB AX, BX ;AX-BX-CF,结果存回AX 
SBB [DI], AH ;[DI]-AH-CF,结果存回内存单元[DI]中
3)减1指令DEC 
DEC指令又称为减量指令,该指令不影响CF 标志位,对其他5个状态标志位产生
影响。指
令格式:DEC OPRD 
功能:操作数OPRD减1后回送OPRD。
说明:操作数OPRD可以是寄存器或存储器操作数,指令可以完成字节或字的减1

第3 章 8086/8088 指令系统 61 
操作。例
如: 
DE C C X 
DEC CL 
DEC BYTE PTR [ARRAY+SI] 
4)操作数求补指令NEG 
指令格式:NEG OPRD 
功能:(0-OPRD)结果送回OPRD,即对OPRD包括符号位在内逐位取反后加1,结果
回送到OPRD。
说明:OPRD可以是寄存器或存储器操作数。如果操作数非0,则指令的执行使CF= 
1,否则CF=0。NEG指令的执行对6个状态标志位都产生影响。
【例3-6】 MOV AL,31H 
NEG AL; AL=CFH,标志位CF=1,PF=1,AF=1,ZF=0,SF=1,OF=0 
5)比较指令CMP 
比较指令CMP用于比较两个数的大小,不外乎大于、小于、等于、大于或等于、小于或
等于几种情况。指令执行结束后,通过检测状态标志位的值,就可以判定是哪一种情况,程
序可以据此设定执行方向,因此,比较指令后面常跟有条件转移指令。
指令格式: 
CM P OP RD 1, O PR D2 
功能:OPRD1减去OPRD2,结果并不回送给OPRD1。CMP指令的执行影响6个状
态标志位。
说明:指令的执行不影响两个操作数,操作数不变,但影响6个状态标志位。OPRD1 
可以是寄存器或存储器操作数,OPRD2可以是立即数、寄存器或存储器操作数。
例如: 
CM P A L, A H ;AL 与AH 比较
CMP AX, BX ;AX 与BX 比较
CMP [SI+DATA], AX ;[SI+DATA]连续两个存储单元的数与AX 比较
CMP CL, 8 ;CL 与8 比较
CMP POINTER[BX], 100H ;[BX+POINTER]连续两个存储单元的数与100H 比较
【例3-7】 
CM P A L, 0 ;AL 与0 比较 
JE EQUA ;若相等,则转移到EQUA 处继续执行,否则顺序执行下一条指令 
… 
EQUA: CMP BL, CL ;BL 与CL 比较 
JA GOON ;若BL 大于CL,则转移到GOON 处执行,否则顺序执行下一条指令 
… 
如果希望实现BL小于CL,则转移,可以使用JB 条件转移指令。如果希望实现BL大
于或等于CL,则转移,可以使用JAE 条件转移指令。如果希望实现BL小于或等于CL,则