目录
第四章 寻址方式与指令系统... 2
4.1 指令系统概述... 2
4.1.1 指令的基本概念... 2
4.1.2 指令格式... 2
4.1.3 8086汇编语言格式... 2
4.1.4 指令的执行... 3
4.2 8086寻址方式... 3
4.2.1 数据寻址方式(程序寻址方式)... 3
4.2.2 指令寻址方式... 7
4.3 8086指令系统... 9
4.3.1 数据传送指令... 9
4.3.2 算术运算指令... 11
4.3.3 逻辑运算指令... 14
4.3.4 移位指令... 14
4.3.5 串操作指令... 15
4.3.6 程序控制指令... 16
4.3.7 处理器控制指令... 18
附录... 20
1、 程序:能够完成一个完整任务的一系列有序指令的集合。
指令:指示计算机进行某种操作的命令;不同的CPU能执行的指令种类、数量均不同。
指令系统:一台计算机所能执行的全部指令的集合。
2、系列计算机:基本指令系统相同、基本体系结构相同的一系列计算机。
3、机器指令(指令字):计算机能直接理解和执行的二进制编码指令。
汇编指令:用助记符代替二进制指令,方便记忆和书写。
1、汇编指令由操作码字段和操作数字段构成。
2、相关概念
操作码:规定指令所执行的操作;
操作数:地址码,直接给出参与运算的操作数或者描述操作数地址信息;
指令字长度:一个指令字中包含二进制代码的位数。
机器字长:指计算机能直接处理的二进制数据的位数,它决定了计算机的运算精度。
单字长指令:指令字长度等于机器字长的指令。
半字长指令:指令字长度等于半个机器字长度的指令。
双字长指令:指令字长度等于2个机器字长度的指令。
3、在一个指令系统中,如果各种指令字长度是相等的,称为等长指令字结构;如果各种指令字长度随指令功能而异,比如有的指令是单字长指令,有的指令是双字长指令,就称为变字长指令字结构。
1、8086指令的一般形式为:
标号: 操作码操作数; 注释
其中,标号和注释都是可选项。标号表示该指令在代码段中的偏移地址; 注释对该指令进行说明,不参加指令的执行。按照指令中所含操作数的个数,8086指令可划分为双操作指令、单操作指令和无操作指令。
2、几种形式的操作指令
①双操作数指令(两地址指令)
大多数指令需要两个操作数,分别为源操作数和目标操作数,指令运算结果存入目标操作数的地址中,操作数中原有的数据被取代。
注:双操作数指令必有一个操作数存放于寄存器中,不能两个操作数同为存储器操作数。
②单操作数指令(一地址指令)
指令中给出的单操作数通常为目标操作数,运算后存放运算结果,另一个操作数由指令隐含指定,在运算前提供。
③无操作数指令(零地址指令)
④三操作数指令(三地址指令)
要执行的程序段的指令,均保存在存储器中,当计算机需要执行一条指令时,首先产生这条指令的相应地址,并根据地址号打开相应的存储单元,取出指令代码,CPU根据指令代码的要求以及指令中的操作数,去执行相应的操作。
1、寻址方式:程序执行时,处理器首先根据指令地址访问相应的内存单元,取出指令代码,CPU再根据指令代码中的操作数字段,取出操作数,去执行相应的操作。其中形成指令地址或者操作数地址的方式即寻址方式。
1、操作数存在方式:
①操作数包含在指令中,即指令的操作数部分就包含着操作数本身。
②操作数包含在CPU的某一个内部寄存器中,这时指令中的操作数是CPU内部的某一个寄存器
③操作数在内存的数据区中,这时指令中的操作数包含着此操作数的地址
④操作数在I/O端口寄存器中。这时指令中的操作数包含着此操作数的所在端口地址
2、立即寻址
操作数直接存放在指令中,紧跟在操作码之后,作为指令的一部分,存放在代码段里,这种操作数称为立即数。常用来给寄存器或者存储单元赋值。
Eg:MOV AX,251 ;把十进制数251送入寄存器AX,251为立即数
注:不能用于单操作数指令,且在双操作指令中,立即数也只能用于源操作数不能用于目标操作数。立即寻址方式只能适用于操作数固定的情况。
3、寄存器寻址
操作数在CPU内部的通用寄存器中,指令中指定寄存器名(机器指令中为寄存器的二进制编号)的寻址方式。寄存器如下:
8位通用寄存器R8:AH、AL、BH、BL、CH、CL、DH、DL
16位通用寄存器R16:AX、BX、CX、DX、SI、DI、BP、SP
4个段寄存器Seg:CS、DS、SS、ES
FLAGS标志寄存器
注:两个操作数不能同时为段寄存器;目的操作数不能是代码段寄存器。
4、存储器寻址
①操作数存放在存储器中,CPU取出指令后,为了获得操作数(对于源操作数)或操作数的存放地址(对于目的操作数)还要再次访问存储器。
EA=BXBP+SIDI+DISP
EA=(基址①)+(变址②)+偏移量③
EA:段地址由段寄存器给出,而偏移地址则要从指令地址码部分计算求得,这个偏移地址称为有效地址;
DISP:指令地址码给出的地址为形式地址或者位移量。
②几种存储器寻址
a.直接寻址:有效地址EA在指令中直接给出,默认段是DS。字在内存中占两个内存单元,低字节在前(低地址),高字节在后(高地址);并以低字节的地址作为字的地址
Eg:MOV AX,[1000H] ;物理地址=DS*10H+1000H=31000H,假设DS=3000H
b.寄存器间接寻址:把内存操作数的有效地址存储于寄存器中,指令中给出存放地址的寄存器名;为了区别于寄存器寻址,寄存器名用“[]”括起。
不同的寄存器所隐含对应的段不同:采用SI、DI、BX 寄存器,数据存于数据段中;采用BP 寄存器,数据存于堆栈段中;操作数的物理地址计算式为:
PA=DS*16+SI / DI / BX
PA=SS*10H+B
Eg:假设DS=3000H,BX=1010H,(31010H)=12H,(31011H)=24H
则指令 MOV AX,[BX] ;物理地址=DS*10H+BX=30000H+1010H=31010H
c.寄存器相对寻址
寄存器相对寻址时,操作数的有效地址分为两部分:一部分存于寄存器中,指令中给出该寄存器名;另一部分以偏移量的方式直接在指令中给出。
有效地址EA为基址寄存器(BX,BP)的内容加偏移量。当EA=(BX)+DISP时:PA=(DS)×16+EA;当EA=(BP)+DISP时:PA=(SS)×16+EA。
d. 基址加变址寻址
基址变址寻址时操作数的EA 分为两部分,分别存于两个寄存器中:一部分存于基址寄存器(BX或BP)中;另一部分存于变址寄存器(SI或DI)中;
指令中分别给出两个寄存器名。操作数的有效地址为:EA1=BX+SI / DI 或EA2=BP+SI / DI
e. 相对基址加变址寻址
采用相对基址变址寻址时,操作数的有效地址分为三部分:一部分存于变址寄存器SI 或DI 中;一部分存于基址寄存器BX 或BP 中;一部分为偏移量。
5、I/O端口寻址
①I/O接口电路由接口寄存器组成,需要用编号区别各个寄存器:编号=地址
1、指令寻址方式是指确定下一条将要执行指令地址的方法,有顺序寻址方式和跳转寻址方式。
2、顺序寻址方式:一条一条地按照顺序进行的顺序执行过程。
跳转寻址方式:程序控制类指令使程序转移到目标地址,从目标地址开始执行程序。目标地址既可以跟程序控制指令在同一个逻辑段内(段内转移),也可以在不同的逻辑段内(段间转移)。
一、段内直接寻址
1、段内直接寻址:只改变了IP寄存器的值而不改变CS寄存器的值,在转移指令中直接给出8 位或16 位的相对位移量,指令转向的有效地址为:(当前IP 的内容+相对位移量) -->( IP )
2、位移量为8位时,称段内直接短转移;位移量为16位时,称段内直接近转移
二、段间直接寻址
1、转移指令中直接给出了转向目标的段基址和段内偏移地址,用此地址分别取代(CS)和(IP)中的内容,完成从当前段向另一个段的转移
三、段内间接寻址
由转移指令中指定一个16位寄存器或存储器字单元的内容做为转移的有效地址,直接取代(IP)的内容。
四、段间间接寻址
在转移指令中给出一个存储单元的地址,用该地址所指的两个相邻字单元的内容(32位)来取代(CS)和(IP)中的内容,从而达到段间转移的目的。
数据传送:负责把数据、 地址或立即数送到寄存器或存储单元中。
数据传送指令可分为4种类型:
注意:不能直接把立即数赋值给段寄存器。
传送字或字节指令 MOV
格式: MOV dst, src ;
功能: src →dst
说明:
1)这里的传送实际上是复制,把src的内容复制到dst, src内容不变;
2)src和dst必须类型一致(都是8位或者是16位);
3)dst不能是立即数;
4)两个操作数不能都是存储器操作数;
5)两个操作数不能都是段寄存器操作数;
6)src是立即数时, dst不能是段寄存器, 必须通过通用寄存器作中介;
堆栈是由若干个连续存储单元组成的一段存储区域,按照“后进先出”的原则存取信息。堆栈使用SS段寄存器记录其段地址。栈只有一个出口,即当前栈顶。栈顶是地址较小的一端(低端),它用堆栈指针寄存器SP指定。栈顶是不断移动的,栈底是固定不变的。
堆栈操作指令:进栈指令PUSH;出栈指令POP
入栈格式: PUSH src ;
功能:将src指示的字数据压入当前栈顶, IP除外
出栈格式: POP dst ;
功能:将当前栈顶的字弹出到 dst 中, CS除外
注意几点:
1)因为堆栈指针SP总是指向已经存入数据的栈顶(不是空单元),所以PUSH指令是先将(SP)减2,后将内容压栈(即先修改SP使之指向空单元,后压入数据),而POP是先从栈顶弹出一个字,后将堆栈指针SP加2。
2) PUSH CS是合法的,但是POP CS是不合法的。
3)因为SP总是指向栈顶,而用PUSH和POP指令存取数时都是在栈顶进行的,所以堆栈是“先进后出”或叫“后进先出”的。 栈底在高地址,堆栈是从高地址向低地址延伸的,所以栈底就是最初的栈顶。
4)用PUSH指令和POP指令时只能按字访问堆栈,不能按字节访问堆栈。
5) PUSH和POP指令都不影响标志。
地址传送指令是一类专用于传送地址码的指令,将内存操作数的逻辑地址(段地址或编译地址)传送至指定寄存器,共包括3条指令:LEA,LDS和LES
格式: LEA REG, SRC ;
功能:将SRC操作数的有效地址EA送到寄存器REG中
注意:源操作数必须是存储器操作数,而目的操作数必须是16位通用寄存器。该指令不影响标志位
格式: LDS REG, SRC ;
功能: 从源操作数所指定的存储器单元中取出4个字节的变量地址指 针,把前两个字节(变量的偏移地址)传送到目标操作数,后两个字节(变量的段基址)传送到DS段寄存器中。
注意:变量的16位地址偏移量必须传送至一个16位的通用寄存器,典型为SI。该指令不影响标志位
功能: 从源操作数所指定的存储器单元中取出4个字节的变量地址指针,把前两个字节(变量的偏移地址)传送到目的操作数,后两个字节(变量的段基址)传送到ES段寄存器中。
格式: LAHF ;
格式: SAHF;
格式: PUSHF ;
格式: POPF ;
注意:PUSHF和POPF指令都是无操作数指令。
格式: XCHG DST,SRC ;
功能:将两个操作数(字或字节)相互交换位置
注意:
1)两操作数可以是通用寄存器和存储器;
2)两操作数不能都是存储器操作数;
3)两操作数类型必须一致;
又叫查表转换指令,它可根据表项序号查出表中对应代码的内容。执行时先将表的首地址(偏移地址)送到BX中,表项序号存于AL中。
执行的操作: AL←[(BX)+(AL)];
注意:转换表长度最大为256个表项(字节)。
80x86有专门的I/O指令用于与端口进行通信。8086的I/O指令是IN指令和OUT指令,这两条指令既可以传送字节,也可以传送字,并且都有直接端口寻址和简介端口寻址。如图所示:
注意:只能使用 AL 或 AX 寄存器与 I/ O 设备进行数据交换;间接寻址I/O指令必须使用DX为间址寄存器,指明I/O端口地址
(1)加法与减法指令
1)不带进位加法指令 ADD
格式:ADD DST, SRC;
源操作数:通用寄存器、存储器、立即数
目的操作数:通用寄存器、存储器
执行的操作: DST ← DST + SRC
注意:该指令影响标志位;该指令适合有符号数和无符号数的运算;
2) 带进位加法指令ADC
格式:ADC DST, SRC;
源操作数:通用寄存器、存储器、立即数
目的操作数:通用寄存器、存储器
执行的操作: DST ← DST + SRC + C
功能:主要用于多字节运算
注意:该指令影响标志位;该指令适合有符号数和无符号数的运算;
3)自增指令INC
格式: INC OPRD
操作数:通用寄存器、存储器 (不能是段寄存器或立即数)
执行的操作: OPRD ←OPRD + 1
功能: 用于在循环中修改地址指针及循环次数等。
注意:该指令影响标志位;该指令将操作数视为无符号数;该指令不影响 进位标志 C
4) 不带借位减法指令SUB
格式:SUB DST, SRC
源操作数:通用寄存器、存储器、立即数
目的操作数:通用寄存器、存储器
执行的操作: DST ← DST – SRC
注意:该指令影响标志位;该指令适合有符号数和无符号数的运算;
5)带借位减法指令SBB
格式: SBB DST, SRC
源操作数:通用寄存器、存储器、立即数
目的操作数:通用寄存器、存储器
执行的操作: DST ←DST - SRC –C
注意:该指令影响标志位;该指令适合有符号数和无符号数的运算;
6)自减指令DEC
格式: DEC OPRD
操作数:通用寄存器、存储器 (不能是段寄存器或立即数)
执行的操作: OPRD ←OPRD - 1
功能: 用于在循环中修改地址指针及循环次数等。
注意:该指令影响标志位;该指令将操作数视为无符号数;该指令不影响 进位标志 C
7)取反指令NEG
格式: NEG OPRD
操作数:通用寄存器、存储器
执行的操作: 求补指令,将操作数按位取反后加1,再送回操作数。
具体功能:对正数的补码求补变为其负数的补码;对负数的补码求补变为其正数的补码。
利用NEG指令可以求负数的绝对值。
注意:该指令影响标志位;
8) 比较指令CMP
格式:CMP DST, SRC
源操作数:通用寄存器、存储器、立即数
目的操作数:通用寄存器、存储器
执行的操作: DST – SRC
比较指令主要用于两个数之间的关系:大、小、相等;仅仅改变了标志寄存器的内容,两操作数的值保持不变;
注意:该指令影响标志位;该指令同 SUB , 但其不保存运算结果;该指令后面通常跟一条转移指令,根据标志位产生不同的程序分支。
在分支程序设计中,常用CMP指令来产生条件,其后往往跟着一条条件转移指令,由CMP指令为条件转移指令提供控制转移的依据;转移指令如图所示:
(2)乘法指令与除法指令
1) 无符号数乘法MUL和带符号乘法IMUL
①无符号数乘法MUL:
格式:MUL SRC
源操作数:通用寄存器、存储器(不能是立即数)
目的操作数: DX, AX (隐含)
执行的操作:
字节操作: AH,AL← AL*(SRC)
字操作: DX,AX← AX*(SRC)
注意:该指令影响标志位;
若结果的高半部分(字节 相乘为AH, 字相乘为DX):
为0 则 C=0, O=0;
为1 则 C=1, O=1;
②带符号乘法IMUL:
格式:IMUL SRC
源操作数:通用寄存器、存储器(不能是立即数)
目的操作数: DX, AX (隐含)
执行的操作:
字节操作: AH,AL← AL*(SRC)
字操作: DX,AX← AX*(SRC)
注意:该指令影响标志位;
若结果的高半部分不是低半部分的符号扩展的话:
则 C=1, O=1;
否则 C=0, O=0;
2) 除法指令
无符号数除法指令: DIV SRC
带符号数除法指令: IDIV SRC
执行操作:
字节操作 (AL) ←(AX) / (SRC) 的商
(AH) ← (AX) / (SRC) 的余数
字操作 (AX) ← (DX, AX) / (SRC) 的商
(DX) ← (DX, AX) / (SRC) 的余数
(3)符号扩展指令
1)字节扩展成字指令 CBW
格式: CBW ;
功能:将 AL 中的符号位扩展到 AH 中,AX 为一个带符号的16为数
2)字扩展成双字指令CWD
格式: CWD ;
功能:将 AX 中的有符号数的符号位扩展到 DX 中,DX, AX 中的数成为一个带符号双字
(4)十进制算术运算指令(BCD码调整指令)
8086提供了6条BCD码调整指令:DAA,DAS,AAA,AAS,AAM,AAD
格式: DAA ;
指令功能:对在AL中两个压缩型BCD数相加的结果,调整成压缩型BCD数在AL中;
调整方法:若AL低4位>9或AF=1,则AL寄存器内容加06H,且将AF置1;若AL高4位>9或CF=1,则AL寄存器内容加60H,且将CF置1;
格式:DAS;
指令功能:对在AL中两个压缩型BCD数相减的结果,调整成压缩型BCD数在AL中;
调整规律: AL低4位>9 或 AF=1 AL=AL-06H, AF=1;
AL高4位>9 或 CF=1 AL=AL-60H, CF=1;
格式:AAA
指令功能:对在AL中两个非压缩型BCD数相加的结果,调整成非压缩型BCD数在AL中;
标志寄存器:该指令不影响PF、 ZF、 SF、 OF。
格式:AAS;
调整后 AL 中高四位清零,如果 AF = 1 , CF = 1, AH-1→ AH
注意:此指令应紧跟在 SUB, SBB, DEC 指令之后
格式:AAM;
调整的结果在 AX 中, AH 和 AL 中分别为 高位 和 低位 非压缩BCD码;
注意:此指令应紧跟在 MUL 指令之后(AL/10 商→AH,余数→ AL);
格式:AAD;
方法:AL←AH×10+AL
AH←0;
逻辑运算指令如图所示:
逻辑运算指令的操作数为字或字节,运算是按二进制位进行;
移位指令包括移位指令和循环移位指令,可以实现字节或字移位;
如图所示:
注意:移一位时, CNT = 1;当移动多位时, CNT 应为 CL, CL中的数为移位位数;
串(string):是指含有字母、数字的一系列字节或字数据;
数据串元素:是指组成数据串的字节或字;
串操作指令:就是用一条指令实现对一串字符或数据的操作;
注意:源串在数据段中: 用 SI 指示串首元素在数据段的有效地址。
目的串在扩展段中: 用 DI 指示目的串首元素在扩展段内的有效地址。
每做一次串操作: 自动修改指针SI 和 DI ,使指针指向下一个串元素。
8086提供了5条基本串操作指令,如图所示:
格式:REP
功能:对跟在REP后面的串操作指令重复执行;
CX ≠ 0 时,重复执行串操作。每执行一次串操作, CX- 1→ CX,
当 CX= 0时,停止执行串操作,转向执行下一条指令;
用于存储器中数据块的搬家;
注意:该指令用在MOVS, STOS, LODS指令前;
格式:REPE/REPZ功能:对跟在REPE后面的串操作指令重复执行
条件为: CX ≠ 0 且 ZF = 1。
每执行一次串的比较或扫描的操作, CX- 1→ CX,当满足上述条件,
重复执行串操作 。当 ZF = 0 或 CX = 0 时,停止串操作的执行
格式:REPNE
功能:对跟在REPNZ后的串操作指令重复执行
条件为: CX ≠ 0 且 ZF = 0。
每执行一次串的比较或扫描的操作, CX- 1→ CX,当满足上述条件,
重复执行串操作。直至 CX = 0 或 ZF = 1 时,停止串操作的执行。
用于比较两个串中的元素都不相等或在串中扫描某个元素
8086 的指令系统共有五类转移指令:无条件转移;条件转移;循环控制;过程调用和返回;中断;
转移指令包括无条件转移指令、条件转移指令和重复控制指令
JMP指令使程序无条件地转移到目标地址,从目标地址开始执行程序。其4中方式如图所示:
条件转移指令能够对一个或几个状态标志位进行测试,判定是否满足转移条件,如果条件满足,就转移到指令指出的目的地去执行指令,否则顺序执行程序。
其格式及转移条件与标志位的关系如图所示:
循环控制指令位于循环程序的首部或尾部,控制程序的走向,实现循环过程。循环控制指令都是具有SHORT属性的段内相对转移。
8086CPU提供了4条循环控制指令如图所示:
在程序设计时,通常将具有独立功能的部分程序段编写成子程序,供其他程序在需要时进行调用。
主程序:调用子程序的程序;
8086CPU位字程序的调用、返回提供了两条指令:CALL指令和RET指令,如图所示:
格式:INT n;n为中断类型号;
格式:IRET; 其作用类似子程序返回指令
标志位处理指令可以设置或清除某个指定的标志位,而不影响其他标志位。它们都是无操作数指令,指令格式及功能如图所示:
其他处理器控制指令如图所示:
这些指令的共同特点时执行结果不影响标志位。