第 3章 8086的寻址方式和指令系统概述
3.1 8086/8088寻址方式
3.2 指令的机器码表示方法
3.3 8086指令系统
1,指令,让计算机完成某种操作的命令称为指令。
2,指令系统,指令的集合即为指令系统。
3,指令的一般格式:
[标号,] 操作码 [操作数 ] [,操作数 ] ; [注释 ]
计算机中的指令由标号、操作码字段和操作数字段组成。
[ ],任选项。
标号字段,是一个任选字段,性质为符号偏移量,一般用于标记跳转指令的目的地址.在汇编过程中标号会被替换为一个 16位的数值偏移量.标号必须位于语句开头,结尾必须使用冒号。
操作码 字段,也称为 指令助记符,指令助记符是必不可少的,指计算机所要执行的操作,或称为指出操作类型,是一种助记符。
操作数 字段,指在指令执行操作的过程中所需要的操作数。该字段除可以是操作数本身外,也可以是操作数地址或是地址的一部分,还可以是指向操作数地址的指针或其它有关操作数的信息。
注释字段,是一个任选字段,用于说明程序片段或指令的功能,
汇编过程中不处理这样的字段,它只是用于提高源程序的可读性.注释必须使用分号作为开始。注释是对该条或该段程序的解释,可选项。
不同的计算机有不同的指令系统,汇编语言的指令语句都与机器指令一一对应,汇编语言通过汇编程序将其翻译成机器指令代码(目标代码),让 CPU执行某种操作。
3.1 8086/8088寻址方式寻址方式,指令中用于说明操作数所在地址的方法,或者说是为获取实际操作数地址而采取的方法称为寻址方式 。 8086/ 8088的基本寻址方式有七种 。
3.1.1 立即寻址
3.1.2 直接寻址
3.1.3 寄存器寻址
3.1.4 寄存器间接寻址
3.1.5 寄存器相对寻址(直接变址寻址、变址寻址)
3.1.6 基址变址寻址
3.1.7 相对基址变址寻址
3.1.1 立即寻址定义,操作数直接由指令提供的寻址方式称为 立即寻址方式 。
在立即寻址方式中所提供的操作数直接包含在指令中 。 它紧跟在操作码的后面,与操作码一起放在代码段区域中 。 如图所示 。
例如,MOV AX,3000H
立即数,直接由指令提供的具体操作数称为立即数 。
特点:
( 1) 立即数可以是 8位的,也可以是 16位的 。 若是 16位的,则存储时低位在前,高位在后 。 只能是整数,不能是小数,变量或其它数据类型 。
( 2) 立即数只能作为源操作数,立即寻址主要用来给寄存器或存储器赋初值 。
( 3)速度快(操作数直接由指令中获得,不需要运行总线周期)
( 4)立即数作为指令操作码的一部分与操作码一起放在代码段区域中。
( 5)指令的长度较长,灵活性较差。
【 例 3.1】 MOV AX,10
执行后 ( AX) =?
其中:源操作数为立即寻址方式,立即数为 10,存放在指令的下一单元 。
图形表示:
执行,10→AX
执行后,( AX) =000AH
3.1.2 直接寻址定义,操作数的有效地址 EA直接由指令直接提供的寻址方式称为直接寻址方式 。
在直接寻址方式中操作数地址的 16位偏移量直接包含在指令中,它与操作码 一 起存放在代码段区域,操作数一般在数据段区域中,它的地址为数据段寄存器 DS加上这 16位地址偏移量 。
如图所示 。
例如,MOV AX,DS,[2000H];
特点:
( 1) 如果指令中没有指明操作数存放在哪一段,则系统默认为数据段 DS。 如上例可写成,MOV AX,[2000H]
( 2) 操作数的有效地址与操作码 一 起存放在代码段区域,操作数一般在数据段区域中 。
( 3) 直接寻址是对存储器进行访问时可采用的最简单的形式 。
这种寻址方法是以数据段的地址为基础,可在多达 64KB的范围内寻找操作数 。
( 4) 操作数的实际地址为数据段寄存器 DS左移 4位加上操作数的有效地址 ( 16位地址偏移量 ) 16位地址偏移量 。
( 5) 段超越前缀,如果要对除 DS以外的其他段寄存器 ( 代码段,
堆栈段和附加段 ) 所指出的存储区进行直接寻址,应在指令中指定段寄存器 -----段超越前缀 。 如:
MOV AX,[2000H] ;数据段 ( 可省略 DS )
MOV BX,ES,[3000H] ;操作数在附加段 ES ( 不能省略 ES )
( 6) 直接寻址的地址如果是数值地址,则必须用,[ ]”括起来,
以区别立即数 。 允许用 符号地址 ( 即程序中的标号 ) 代替数值地址 。
【 例 3.2】 寄存器和存储器内容为,( AX) =1212H,BUF为数据段定义的变量,其偏移地址是 2000H,( DS) =3000H,( 32000H)
=4545H。
执行指令,MOV AX,BUF
执行后,( AX) =?
图形表示:
执行,( 32000H) → ( AX)
执行后,( AX) =4545H
3.1.3 寄存器寻址定义,操作数直接存放在 CPU的内部寄存器中 ( 如:寄存器 AX、
BX,CX,DX等 ) 的寻址方式称为寄存器寻址方式 。
例如,MOV DS,AX
MOV AL,BH
特点:
( 1)操作数放在 CPU的通用寄存器中。
16位,AX,BX,CX,DX,SI,DI,SP,IP
8位,AH,AL,BH,BL,CH,CL,DH,DL
通常放在 AX,AH,AL中,因为 AX是累加器,结果一般放在 AX
中,这样指令会更短些。
( 2)采用寄存器寻址时,操作就在 CPU内部进行,不需要使用总线周期,速度快。
( 3)一条指令中,既可以对源操作数采用寄存器寻址,也可以对目的操作数采用寄存器寻址,也可二者均采用寄存器寻址。
【 例 3.3】 下列程序执行后,( AX) =?,( BX) =?
MOV AX,1234H
MOV BX,5678H
ADD AX,BX
该程序中 MOV指令为数据传送指令操作符,ADD指令为加法指令操作符,三条指令皆为双操作数指令 。 第一,二条指令 AX,BX
皆为目的操作数地址,为立即数寻址方式 。 第三条指令中,AX为目的操作数地址,BX为源操作数地址 。 源地址和目的地址皆为寄存器寻址方式 。
3.1.4 寄存器间接寻址操作数是在存储器中,但是,操作数的有效地址 EA( 偏移量 )
在以下四个寄存器 SI,DI,BP,BX之一中 。 可以分成两种情况:
( 1) 以 SI,DI,BX间接寻址,则通常操作数在现行数据段区域中,
即数据段寄存器 ( DS) × 16加上 SI,DI,BX中的 16位偏移量,为操作数的地址,
例如,MOV AX,[SI],操作数地址是,( DS) ╳ 16 +( SI)
( 2) 以寄存器 BP间接寻址,则操作数在堆栈段区域中 。 即堆栈段寄存器 ( SS) × 16与 BP的内容相加作为操作数的地址,
例如,MOV AX,[BP],操作数地址是,( SS) ╳ 16 +( BP)
若在指令中规定是段超越的,则 BP的内容也可以与其它的段寄存器相加,形成操作数地址 。
例如,MOV AX,DS,[BP],操作数地址是,( DS) ╳ 16 +( BP)
特点:
( 1)指令中的基址寄存器与段寄存器的配对关系为:
BX,SI,DI----DS,BP----SS
( 2)如果要对其他段寄存器所指出的区域进行寻址,则在指令中应指出指定超越段前缀。
( 3)寄存器间接寻址方式适用于表格处理。执行完一条指令后,
只需修改寄存器的内容( +1,+2,…… )就可取出表格中的相应项。
( 4)间址的寄存器用,[ ]”括起来,以区别寄存器寻址。
AX
AH AL
数据段 物理地址
A 0 H 21000H
50H 20001H
56H 20002H
【 例 3.4】 指令 MOV AX,[BX]
若 ( DS) = 2000H,( BX) = 1000H,
物理地址= 20000H+ 1000H= 21000H。
指令执行前,( AX) = 2030H,( 21000H) = 0A0H,( 21001H)
= 50H,
指令执行后,( AX) = 50A0H,( 21000H) = 0A0H,( 21001H)
= 50H。
指令执行情况如下:
3.1.5 寄存器相对寻址(直接变址寻址、变址寻址)
寄存器相对寻址方式是在指令中给定一个基址寄存器 ( 或变址寄存器 ) 名和一个 8位或 16位的相对偏移量,两者之和作为操作数的有效地址 EA。 对 BX,SI,DI这三个间址寄存器,指示的是数据段中的数据,而用 BP作间址寄存器,则指示的是堆栈段中的数据 。
汇编格式,X[R]( X表示位移量,是 8位或 16位二进制补码表示的有符号数,R表示寄存器 ) 。
功能,操作数存放在存储器,寄存器 R的内容加位移量 X为操作数的偏移地址 EA。
有效地址 EA计算方法如右:
特点:
( 1) SI,DI,BX默认的段寄存器为 DS,BP默认的段寄存器为 SS。
( 2)可以使用段寄存器超越前缀来寻址其他段。
( 3)寄存器相对寻址方式适用于表格处理。表首的地址可设置为偏移量指针,利用修改基址或变址寄存器的内容来获得表格中的内容。
【 例 3.5】 设执行前,( AX) =0040H,( BX) =0030H,( DS)
=2000H,( 20036H) =0050H
执行指令,ADD 6[BX],AX
执行后,( AX) =?,( BX) =?,( DS) =?,( 20036H) =?
图形表示如下:
执行前,( AX) =0040H,( BX) =0030H,( DS) =2000H,
( 20036H) =0050H
执行指令,ADD 6[BX],AX
执行:( 20036H) +( AX) → ( 20036H)
执行后:( AX) =0040H,
( BX) =0030H,
( DS) =2000H,
( 20036H) =0090H。
图形表示如右:
3.1.6 基址变址寻址把 BX和 BP看成是基址寄存器,把 SI,DI看成是变址寄存器,
把一个基址寄存器( BX或 BP)的内容加上一个变址寄存器( SI或
DI)的内容作为操作数的偏移地址。但指令中不能同时出现两个基址寄存器或两个变址寄存器。
操作数在存储器中,其有效地址 EA由 ( 基址寄存器 ) +
( 变址寄存器 ) 形成 。
特点:
( 1) 基址寄存器为 BX时,默认为数据段 DS,基址寄存器为 BP时,
默认为堆栈段 SS;变址寄存器为 SI,DI。
( 2) 可以使用段寄存器超越前缀来寻址其他段 。
( 3) 基址变址寻址方式适用于数组或表格处理 。 首地址可设置在基址寄存器中,变址寄存器用于访问数组中的元素或表格中的内容 。 基址寄存器和变址寄存器均可以修改,非常灵活 。
【 例 3.6】 MOV AL,[BX+ SI]( 或 MOV AL,[BX][SI])
若指令执行前,( DS) = 1000H,( BX) = 0010H,
( SI) = 0002H,( 10012H) = 45H
则 有效地址 EA= ( BX) + ( SI) = 0012H,
实际地址 PA= ( DS) × 10H+ EA= 10012H
指令执行后 ( AL) = 45H。
3.1.7 相对基址变址寻址把 BX和 BP看成是基址寄存器,把 SI,DI看成是变址寄存器,
把一个基址寄存器( BX或 BP)的内容加上一个变址寄存器( SI或
DI)的内容,再加上指令中指定的 8位或 16位偏移量(当然要以一个段寄存器作为地址基准)作为操作数的偏移地址,如图所示。
相对基址变址寻址德表示形式:
6[BX][SI]
或 [BX+6][SI]
或 [BX+6+SI]
其中:方括号 [ ]有相加的含义操作数在存储器中,其有效地址 EA由 ( 基址寄存器 ) + ( 变址寄存器 ) +相对偏移量形成 。
特点,同基址变址寻址方式,比基址变址寻址方式更灵活 。
表 3-1 段寄存器使用的基本约定访问存储器类型 默认段寄存器 可指定段寄存器 段内偏移地址来源取指令码 CS 无 IP
堆栈操作 SS 无 SP
串操作源地址 DS CS,ES,SS SI
串操作目的地址 ES 无 DI
BP用作基址寄存器 SS CS,DS,ES 根据寻址方式求得 有效地址一般数据存取 DS CS,ES,SS 根据寻址方式求得 有效地址注意:
( 1)隐含寻址:操作数隐含在指令中。
如,DA A,操作数隐含在 AL中。
( 2) I/O端口寻址直接 I/O端口寻址:指令中直接提供端口地址。
如,IN AL,60H
间接 I/O端口寻址:指令中直接指出存放端口地址寄存器 DS。
如,MOV DX,303H
IN AL,DX
( 3)一条指令中可以同时存在几种寻址方式。
如,MOV [BX],AL
3.2 指令的机器码表示方法( P65----P70)
阅读:
知识点,汇编语言、机器语言、汇编语言源程序、汇编的方法。
编码方法:了解掌握。
3.3 8086指令系统
8086的指令可以分为五大类
3.3.1 数据传送指令
3.3.2 算术运算指令
3.3.3,逻辑运算和移位指令
3.3.4 字符串处理指令
3.3.5 控制转移指令
3.3.1 传送指令
(阅读教材 P70----P78页的内容)见 P70表 3-3
对标志为的影响,传送指令除标志传送( SAHF,POPF)外,均不影响标志位。
分类,传送指令可分为通用传送指令、堆栈操作指令、交换操作指令,I/O操作指令、目的地址传送指令和标志传送指令六类。
1.通用传送指令一般格式,MOV OPRD1,OPRD2 ;
[目的操作数 OPRD1]← [ 源操作数 OPRD2]
其中,源操作数 OPRD2为,立即数 data、存储器单元地址 mem、
累加器 AX、寄存器 reg、段寄存器 segreg。
目的操作数 OPRD1为,存储器地址 mem、累加器 AX、寄存器 reg、
段寄存器 segreg、指定段寄存器。
功能,完成数据传送 。
规定:
( 1) MOV指令可在 CPU内部寄存器之间或 CPU与存储器之间传送字( 16位)或字节( 8位)数据,但代码段寄存器 CS和指令指针
IP除外。
R←data mem ←data R←R
R← mem mem ←R
segreg( CS,IP除外) ← R或 mem R← segreg
如,MOV AL,BL;
MOV CX,BX;
MOV DS,BX
MOV CL,4
MOV AX,03FFH
MOV SI,057BH
MOV [2000H],25H
MOV [SI],35H
MOV AX,[1000H]
MOV AL,BUFFER; BUFFER为标号
MOV AX,[SI]
MOV [DI],CX
MOV SI,BLOCK[BP]
MOV DS,DATA[SI+BX]
MOV DEST[BP+DI],ES
( 2)立即数不能作为目的操作数,只能作为源操作数。
MOV 1000H,AL; ( ╳ )
( 3) CS,IP不能作为目的操作数。
MOV CS,AX ; ( ╳ )
MOV IP,AX ; ( ╳ )
( 4)除源操作数为立即数外( mem ←data ),两个操作数中必须有一个为寄存器。即不允许在两个存储器单元之间直接传送数据。
MOV [2000H],[1000H] ; ( ╳ )
如需要把地址 (即段内的地址偏移量 )为 AREAl的存储单元的内容,传送至同一段内的地址为 AREA2的存储单元中去,MOV指令不能直接完成这样的传送,但可以 CPU内部寄存器为桥梁来完成这样的传送:
MOV AL,AREAl
MOV AREA2,AL
( 5)通用传送指令 MOV是唯一允许以段寄存器作为操作数的指令,但 不允许通过 MOV指令直接以立即数方式给段寄存器赋值,
不允许在两个段寄存器之间直接传送数据 。可以通过 AX为桥梁来完成这样的传送:
MOV AX,0
MOV DS,AX
( 6) MOV指令不影响标志位。
2,堆栈指令堆栈,在存储器中开辟一段区域,用于存储一些暂时需要保护而以后还要用到数据 ( 如中断现场的保护与恢复,子程序现场的保护与恢复等 ),这个区域称为堆栈 。
堆栈的特点:
堆栈存储数据的原则为后进先出 。
堆栈在存储器中的位置由 SS,SP确定 。 SP指令可由 MOV指令设置 。
堆栈指针 SP在 8086系统中始终指向栈的顶部,即:始终指向最后压入栈中的数据的地址 。
8086系统中栈的操作是以字为单位的 。 执行一次入栈操作,
SP-2,直至 SP=0( SS ) 栈满为止 。 执行一次出栈操作,SP+2。
功能,主要用于保护中间数据,子程序的现场,中断程序的现场等 。
包括入栈 ( PUSH) 和出栈 ( POP) 指令两类 。 仅能进行字运算 。 ( 操作数不能是立即数 )
格式:
⑴ 入栈指令,PUSH OPRD
功能,将数据压入堆栈执行步骤为,先修改堆栈指针 SP,然后将数据压入堆栈 。
SP =SP-2; [SP]=操作数低 8位; [SP+1]=操作数高 8位 。
例如,PUSH BX
执行过程为,SP=SP-1,[SP]=BH; SP=SP-1,[SP]=BL,如图 。
⑵ 出栈指令,POP OPRD
功能,将数据弹出堆栈 。
执行步骤同入栈指令 。 不同的是,先将数据弹出堆栈,然后修改堆栈指针 SP。 ( SP ) = ( SP ) +2。 例如,POP [BX]
规定:
( 1) 堆栈段 SS,栈指针 SP,堆栈只有一个入 /出口 。
( 2) 栈指针 SP在初始化中需要设置 。 在入,出栈操作中,栈指针 SP是自动修改的,以保证 SP始终指向栈顶 。
( 3) 操作数 OPRD可以是 CPU内部的 16位通用寄存器,段寄存器
( CS除外 ) 和内存单元,也可以用除立即寻址外的所有寻址方式,
但不能使立即数 。 入,出栈操作对象必须是 16位数 。
( 4) PUSH,POP指令必须成对使用,在一个程序中不能出现非成对的 PUSH,POP指令 。
3,交换操作指令格式,XCHG OPRD1,OPRD2;
[目的操作数 OPRD1]←→ [ 源操作数 OPRD2]
功能,完成数据交换,把一个字节或一个字的源操作数与目的操作数相交换。
规定:
( 1) 可实现 8位或 16位数据的交换 。 两个操作数的位数必须相同 。
( 2)交换能在通用寄存器与累加器之间、通用寄存器之间、通用寄存器与存储器之间进行。两个操作数中必须有一个为寄存器。
即 不允许在两个存储器单元之间直接交换数据 。
( 3) 段寄存器和立即数不能作为一个操作数 。
( 4) 交换指令 XCHG不影响标志位 。
例如,XCHG AL,CL
XCHG AX,DI
XCHG BX,SI
XCHG AX,BUFFER
XCHG DATA[SI],DH
4,I/O操作指令
I/O操作指令也称为 累加器专用 传送指令,有三种,输入、输出和累加器换码指令(查表指令)指令。
功能,I/O操作指令用于完成累加器( AX/AL)与 I/O端口之间的数据传送功能。
( 1)输入指令 IN
格式,IN AL,PORT ; AL←[PORT] ( B )
IN AX,PORT; AX←[PORT +1][PORT ] ( W )
IN AL,DX ; AL←[DX] ( B )
IN AX,DX ; AX←[DX+ 1][DX] ( W )
其中,PORT 为 8位端口直接地址 。 B为字节操作,W为字操作 。
功能,从 I/O端口输入数据至 AL或 AX。
规定:
输入指令允许把一个字节或一个字由一个输入端口传送到 AL
或 AX中。
当端口地址 ≤ 255时,PORT为 8位端口直接地址。
当端口地址 ≥255时,则必须用 DX间址( 16位端口直接地址)
保存端口地址,这样用 DX作端口寻址最多可寻找 64K个端口。
⑵ OUT 指令格式,OUT PORT,AL; ( AL) → [PORT] ( B )
OUT PORT,AX; ( AX) → [PORT+1][PORT ] ( W )
OUT DX,AL ; ( AL ) → [DX] ( B )
OUT DX,AX ; ( AX) → [DX+1][DX] ( W )
功能,将 AL或 AX的内容输出至 I/O端口 。 该指令将 AL或 AX中的内容传送到一个输出端口 。 其具体 规定 与 IN指令相同 。
注,IN,OUT指令提供了 8位和 16位两种使用方式,选用哪一种,
取决于外设端口的数据总线的宽度。若外设端口的数据总线为 8
位,则只能用 8位指令,使用 AL;若外设端口的数据总线为 16位,
则只能用 16位指令,使用 AX。
( 3)累加器换码指令 XLAT
格式,XLAT ; ( AL ) ← ( ( DS) × 16+ ( BX) +( AL) )
功能,完成一个字节的换码转换 。 主要用于数制转换,函数表查表,代码转换等场合 。
规定,① 寄存器 AL的内容作为某一项到表首的偏移量 ( 256字节的表的下标 ) 。
② 表的基地址在 BX中 ( 表首地址 ) 。
③ 转换后的结果存放在 AL中 。
特点,XLAT指令不影响标志位 。
例如,MOV BX,OFFSET TABLE
MOV AL,8
XLAT ;查表
OUT 40H,AL ; ( AL) = AAH;向 40H口输出 AAH
AAH
TABLE
第 9个字符表长度 256
……
【 例 3.7】 十进制数到共阴极 LED七段码显示段码的转换。
共阳极 LED显示器的段码,0----9分别为,C0,F9H,A4H、
B0H,99H,92H,82H,F8H,80H,90H。
解,设计过程,
( 1)将段码表存到数据段的一片连续的单元中,表首地址
2000H送 BX。
( 2)将待转换的十进制数送 AX。
( 3)换码。
程序,MOV BX,2000H
MOV AL,3
XLAT
5,目的地址传送指令目的地址传送指令共有三条指令
⑴ 取有效地址指令 LEA(Load Effective Address)
格式,LEA OPRD1,OPRD2
或,LEA reg,[add]; ( reg) ← add,add为有效地址功能,把存储器的有效地址 EA送入一个寄存器 reg 。 即把源操作数
OPRD2的 地址偏移量 传送至目的操作数 OPRD1。
规定,① 源操作数必须是一个存储单元地址 。 目的操作数必须是一个 16位的通用寄存器 。
② 传送到 16位的通用寄存器的是存储器的有效地址 EA,而不是该存储单元的内容 。
③ 这条指令通常用于将一个 16位的通用寄存器作为地址指针 。
例,LEA BX,[2728H] ; ( BX ) ← 2728H
LEA BX,[BX+SI] ; ( BX ) ← ( BX+SI )
⑵ 将地址指针装入 DS和另一个寄存器指令 LDS (Load pointer into DS)
格式,LDS OPRD1,OPRD2
或,LDS reg,[add]; ( reg) ← ( add+1 ) ( add)
( DS) ← ( add+3 ) ( add +2 )
功能,把 4字节的地址指针 ( 包括 2字节的段地址和 2字节的偏移量 )
传送到 DS和 reg中,完成一个地址指针的传送 。 指令将段地址送入
DS,偏移量部分送入一个 16位的指针寄存器或变址寄存器 。
规定,① 源操作数可以是一个存储单元地址,或是用通用寄存器作间址的存储单元地址 。 目的操作数必须是一个 16位的通用寄存器 。
② 目的操作数的段地址必须送到 DS 中 。
③ 传送的是存储单元的内容,而不是存储器的有效地址 EA 。
例如,LDS SI,[BX] ;将把 BX所指的 32位地址指针的段地址部分送入 DS,偏移量部分送入 SI。
⑶ 将地址指针装入 ES和另一个寄存器指令 LES (Load pointer into ES)
格式,LES OPRD1,OPRD2
或,LES reg,[add]; ( reg) ← ( add+1 ) ( add)
( ES) ← ( add+3 ) ( add +2 )
规定,这条指令除将地址指针的段地址送入 ES外,其他同 LDS。
例如,LES DI,[BX+COUNT]
如右图所示。
6,标志寄存器传送指令标志寄存器传送指令共有四条指令 。 均影响标志位 。
标志寄存器 FR( 即程序状态字 PSW)
⑴ LAHF ( LOAD AH WITH FLAG)
格式,LAHF; ( AH) ← ( FR ) 0~ 7
功能,将标志寄存器中的 SF(7),ZF (6),AF (4),PF (2)和 CF
(0) ( 即低 8位 ) 传送至 AH寄存器的指定位,空位没有定义 。
⑵ SAHF ( STORE AH WITH FLAG)
格式,SAHF; ( FR) 0~ 7 ← ( AH)
功能,将寄存器 AH的指定位,送至标志寄存器的 SF,ZF,AF、
PF和 CF位 ( 即低 8位 ) 。 根据 AH的内容,影响上述标志位,对
OF,DF和 IF无影响 。
⑶ PUSHF ( PUSH FLAG)
格式,PUSHF;将 FR入栈 。 ( SP) ← ( SP) - 2
(( SP ) +1,( SP )) ← ( FR )
功能,将标志寄存器 FR压入堆栈顶部,同时修改堆栈指针,不影响标志位 。
⑷ POPF ( POP FLAG)
格式,POPF ;将栈顶的内容弹出到 FR中 。
( FR ) ← (( SP ) +1,( SP ))
( SP) ← ( SP) + 2
功能,堆栈顶部的一个字,传送到标志寄存器 FR,同时修改堆栈指针,影响标志位 。
3.3.2 算术运算指令
(阅读教材 P78----P90页的内容)见 P79表 3-6
8086提供加、减、乘、除四种基本算术操作。这些操作都可用于字节或字的运算,也可以用于带符号数与无符号数的运算。 带符号数用补码表示。同时 8086也提供了十进制调整指令,故可以进行十进制算术运算。
参与加、减运算的操作数可如下图所示。
源操作数目的操作数
1,加法指令 (Addition)
⑴ 加法指令 ADD
格式,ADD OPRD1,OPRD2; ( OPRD1 ) ← ( OPRD1) +( OPRD2)
功能,完成两个操作数相加,结果送至目的操作数 OPRD1。
规定,① 源操作数为通用寄存器 reg,存储单元 mem,立即数 data。
② 目的操作数为累加器 AX( AL),任一通用寄存器 reg及存储单元 mem 。
③ 影响 6个标志位 CF,OF,PF,SF,ZF和 AF。
例如,累加器与立即数相加:
ADD AL,30; ( AL) ← ( AL ) +30
通用寄存器与存储单元内容相加:
ADD BX,[3000H];
( BX ) ← ( BX ) +( 3001H ) ( 3000H )
通用寄存器之间内容相加:
ADD DI,CX; ( DI ) ← ( DI ) +( CX )
通用寄存器与存储单元内容相加:
ADD DX,DATA[BX+SI];
( DX) ← ( DX) + (( BX ) +( SI ) + DATA)
存储器操作数与寄存器相加:
ADD BETA[SI],DX;
(( SI ) + BETA ) ← (( SI ) + BETA ) + ( DX)
⑵ 带进位位加法指令 ADC
格式,ADC OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) +( OPRD2 ) +CF
功能,这条指令与 ADD指令类似,区别在于需要加 CF。 ADC指令主要用于多字节运算中 。 与 ADD相同,影响 6个标志位 CF,DF、
PF,SF,ZF和 AF。
【 例 3.8】 若有两个四字节的数,已分别放在自 FIRST和 SECOND
开始的存储区中,每个数占四个存储单元,结果放在 THIRD开始的单元中 。 存放时,最低字节在地址最低处,则程序为:
MOV AX,FIRST
ADD AX,SECOND;进行字运算
MOV THIRD,AX
MOV AX,FIRST+2
ADC AX,SECOND+2
MOV THIRD+2,AX
⑶ 增量 ( 加 1) 指令 INC
格式,INC OPRD ; ( OPRD ) ← ( OPRD ) +1
功能,完成对指定的操作数 OPRD加 1,然后返回此操作数 。 此指令主要用于在 循环程序中修改地址指针和循环次数 等 。
规定:
① 操作数可为通用寄存器 reg,各种寻址方式的存储单元 mem。
② INC指令执行的结果影响 除进位标志 CF以外 的 5个标志位 AF、
OF,PF,SF和 ZF。
如,INC AL ; ( AL ) ← ( AL) +1
INC [BX] ; ( ( BX )) ← (( BX )) +1
2.减法指令 (Subtraction)
⑴ 减法指令 SUB
格式,SUB OPRD1,OPRD2; ( OPRD1) ← ( OPRD1 ) -( OPRD2 )
功能,完成两个操作数相减,即从 OPRD1中减去 OPRD2,结果放在 OPRD1中 。
例如,SUB CX,BX; ( CX ) ← ( CX ) -( BX )
SUB [BP],CL; (( BP)) ← (( BP)) -( CL )
规定,同 ADD。
⑵ 带借位位减法指令 SBB
格式,SBB OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) - ( OPRD2) - CF
SBB指令与 SUB类似,区别在于要减去借位标志 CF的值 。
SBB指令对标志位 AF,CF,OF,PF,SF和 ZF都有影响 。 同
ADC指令一样,SBB指令主要用于多字节运算中 。
⑶ 减量 ( 减 1) 指令 DEC
格式,DEC OPRD ; ( OPRD ) ← ( OPRD ) - 1
功能,完成对指定的操作数 OPRD减 1,然后返回此操作数 。 此指令主要用于在循环程序中修改地址指针和循环次数等 。
在相减时,把操作数作为一个无符号二进制数来对待 。 指令执行的结果,DEC指令执行的结果影响 除进位标志 CF以外 的 5个标志位 AF,OF,PF,SF和 ZF。
规定,同 INC。
例如,DEC [SI] ; (( SI ) )←( ( SI ) )- 1
DEC CL; ( C L ) ← ( C L ) - 1
⑷ 求补指令 NEG
格式,NEG OPRD
功能,取补 (NEGDate)----对操作数取补,即用零减去操作数,再把结果送回操作数 。
操作数 为通用寄存器 reg,存储单元 mem
例如,NEG AL ; ( AL) ← 0 -( AL )
( AL= 0011 1100) 则取补后为 1100 0100,即 0000 0000- 0011 1100= 1100 0100
若在字节操作时对 -128( 或在字操作时对 -32768取补 ),则操作数没变化,但标志 OF置位 。
此指令影响标志 AF,CF,OF,PF,SF和 ZF。 此指令的结果一般总是使标志 CF=1。 除非在操作数为零时,才使 CF=0。
⑸ 比较指令 CMP
格式,CMP OPRD1,OPRD2 ; ( OPRD1 ) -( OPRD2 )
功能,比较指令完成两个操作数相减,使结果反映在标志位上,
但并不把结果送回目的操作数 (即比较指令是不带回送的减法 )。
比较指令主要用于比较两个数之间的关系 。 在比较指令之后,根据 ZF标志即可判断两者是否相等 。
相等的比较:
① 若两者相等,相减以后结果为零,ZF标志为 1,否则为 0。
② 若两者不相等,则可在比较指令之后利用其它标志位的状态来确定两者的大小 。
大小的比较:
如果是两个无符号数 ( 如 CMP AX,BX) 进行比较,则可以根据 CF标志的状态判断两数大小 。 若结果没有产生借位 (CF=0),
显然 AX≥BX;若产生了借位 ( 即 CF= 1),则 AX< BX。
注,一般情况下,CMP指令后面经常会有一条条件转移指令,用来检查标志位的状态是否满足某种关系 。
例如,CMP AL,100;
将 ( AL ) 与 100比较,AL的内容不变,结果影响标志位 。
CMP DX,DI ;
将 ( DX ) 与 ( DI ) 比较,DX,DI的内容均不变,结果影响标志位 。
CMP CX,COUNT[BP] ;
将 ( CX ) 与 (( BP ) + COUNT) 比较,CX,BP、
(( BP) + COUNT) 的内容均不变,结果影响标志位 。
CMP COUNT[SI],AX ;
将 (( SI ) + COUNT ) 与 ( AX ) 比较,AX,SI,
(( SI ) + COUNT)) 的内容均不变,结果影响标志位 。
CMP指令执行后的标志位状态:( CMP A,B)
( 1) A,B均为无符号数时,ZF=0,则 A=B; CF=1,则 A<B ;
CF=0,则 A>B 。
( 2) A,B均为符号数,其均为正数,ZF=1,则 A=B; SF=1,
则 A<B ; SF=0,则 A>B 。
( 3) A,B均为符号数,其均为负数,ZF=1,则 A=B; SF=1,
则 A<B ; SF=0,则 A>B 。
( 4) A,B一个为正数,一个为负数时:
OF=0,若 SF=0,则 A>B 。
若 SF=1,则 A<B 。
OF=1,若 SF=0,则 A<B 。
若 SF=1,则 A>B 。
0111,1111(127)
0011,010(50)
+
1011,0001(-79)
127-(-50)=177
因为溢出了所以,OF=1,SF=1
同样,如果 A=-50,B=127,则结果是 OF=1,SF= 0。
综上所述:
( 1) A=B 用 ZF=1 判断 。
( 2) 两个无符号数的大小用 CF判断。
CF=1,A<B; CF=0,A>B。
( 3) 两个符号数的大小用 SF⊕ OF判断。
SF⊕ OF=1,A<B; SF⊕ OF=0,A>B。
在 8086系统中,有两条转移指令可实现 SF⊕ OF的判断。
JG/JNLE(大于,SF⊕ OF=0且 ZF=0 )
JL/JNGE (小于,SF⊕ OF=1且 ZF=0 )
3,乘法指令乘法指令分为无符号乘法指令和带符号乘法指令两类,
( 1)无符号乘法指令 MUL( 8位 /16位)
格式,MUL OPRD ;
8位,( AX) ← ( AL) ╳ ( OPRD )
16位,( DX) ( AX) ← ( AX) ╳ ( OPRD )
功能,完成字节与字节相乘,字与字相乘,且默认的操作数放在
AL或 AX中,而源操作数由指令给出 。 8位数相乘,结果为 16位数,
放在 AX中; 16位数相乘结果为 32位数,高 16位放在 DX,低 16位放在 AX中 。
规定:
① 源操作数只能是通用寄存器 reg和存储单元 mem,不能为立即数 。
② 影响 6个标志位 CF,DF,PF,SF,ZF和 AF。
例如,MOV AL,FIRST;
MUL SECOND ;结果为 AX=FIRST× SECOND
( 2) 带符号数乘法指令 IMUL( 8位 /16位 )
格式,IMUL OPRD ;
8位,( AX) ← ( AL) ╳ ( OPRD )
16位,( DX) ( AX) ← ( AX) ╳ ( OPRD )
功能,这是一条带符号数的乘法指令,同 MUL一样可以进行字节与字节、字和字的乘法运算。结果放在 AX或 DX,AX中。当结果的高半部分不是结果的低半部分的符号扩展时,标志位 CF
和 OF将置位。
规定,同 MUL 。
4,除法指令除法指令可分为以下四类:
(1) 无符号数除法指令 DIV ( 8位 /16位 )
格式,DIV OPRD;
8位,( AL) ← ( AX) /( OPRD ) …… ( AH) ( 余数 )
16位,( AX) ← ( DX) ( AX) /( OPRD ) …… ( DX ) ( 余数 )
功能,完成字节与字节除法,字与字除法,且默认目的操作数放在
AX或 DX,AX中,源操作数由指令给出,结果放在 AL,AX中 。
规定,① 基本同 MUL。 但在除法指令中,除数在源操作数中 。 在字节运算时被除数在 AX中;商在 AL中,余数在 AH中 。 字运算时被除数为 DX,AX构成的 32位数,商在 AX中,余数在 DX中 。
② 除法运算中,源操作数可为除立即寻址方式之外的任何一种寻址方式,且指令执行后所有的标志位都不确定,即或是 0,或是 1,但都无意义 。
例如,AX=2000H,DX=200H,BX=1000H,则 DIV BX执行后,
AX=2002H,DX=0000。
( 2) 带符号数除法 IDIV ( 8位 /16位 )
格式,IDIV OPRD;
8位,( AL) ← ( AX) /( OPRD ) …… ( AH) ( 余数 )
16位,( AX) ← ( DX) ( AX) /( OPRD ) …… ( DX ) ( 余数 )
功能,该指令执行过程同 DIV指令,但 IDIV指令认为操作数的最高位为符号位,除法运算的结果商的最高位也为符号位 。
规定,基本同 DIV。
由于除法指令中的字节运算要求被除数为 16位数,而字运算要求被除数是 32位数,当被除数不够位数时,需要对高 8位的 AH
( 或高 16位的 DX) 进行扩展 。
对于无符号数,AH,DX的扩展是将它们请 0。 对于有符号数,
在 8086/8088系统中往往需要用符号扩展的方法取得被除数所要的格式,因此指令系统中包括两条符号扩展指令 。
(3) 字节转换为字扩展指令 CBW
格式,CBW
功能,该指令执行时将 AL寄存器的最高位扩展到 AH,即若 AL
的 D7=0,则 AH=0;若 AL的 D7=1,则 AH=0FFH。
CBW指令不影响标志位 。
(4) 字转换为双字扩展指令 CWD
格式,CWD
功能,该指令执行时将 AX寄存器的最高位扩展到 DX,即若 AX
的 D15=0,则 DX=0;若 AX的 D15=1,则 DX=0FFFFH。
CWD指令不影响标志位 。
5,十进制调整指令计算机中的算术运算,都是针对二进制数的运算,而人们在日常生活中习惯使用十进制 。 为此在 8086/8088系统中,针对十进制算术运算有一类十进制调整指令 。
在计算机中人们用 BCD码表示十进制数,对于 BCD码,计算机中有两种表示方法:
压缩 BCD码,即规定每个字节表示两位 BCD数;
非压缩 BCD码,即用一个字节表示一位 BCD数,在这字节的高四位用 0填充 。
例如,十进制数 25D,压缩 BCD数为 25H;非压缩 BCD数为
0205H,用两字节表示 。 数字的 ASCII码是一种非压缩 BCD码
( 高 4位为 0011H),0----9的 ASCII码是 30H----39H。
每条十进制调整指令在使用时都与相应的算术运算指令配合,
并自动对相应的算术运算指令结果进行相应的十进制调整 。
相关的 BCD转换指令见下表。
十进制调整指令指令格式 指令说明
DAA 压缩的 BCD码加法调整
DAS 压缩的 BCD码减法调整
AAA 非压缩的 BCD码加法调整 ( ASCII码调整 )
AAS 非压缩的 BCD码减法调整 ( ASCII码调整 )
AAM 乘法后的 BCD码调整
AAD 除法 前 的 BCD码调整
(1)AAA加法的 ASCII调整指令调整原则:
a.若 AL的低 4位 >9或 AF= 1,则
AL=AL-6;
用与操作将 AL高 4位清零;
AF置 1,CF置 1,AH= AH+1;
b.否则,将 AL寄存器高 4位清 0。
例题:若 AL= BCD9,BL= BCD5,求两数之和。设 AH= 0,则
ADD AL,BL
AAA
0000 1001 … 9
0000 0101 … 5+
0000 1110 … 低 4位 >9+
0000 0110 … 加 6调整
0001 0100
0000 1111 … 清高 4位∧
0000 0100 … AL= 4
CF=1,AF=1,AH =1
结果为 AX= 0104H,表示非压缩十进制数 14
(2)DAA加法的十进制调整指令功能:将 2个压缩的 BCD数相加后的结果调整为正确的压缩 BCD数。
相加后的结果必须在 AL中,才能使用 DAA指令。
调整过程为:
若做加法后 AL中的低半字节 >9或 AF= 1,则
AL= AL+ 6,对低半字节进行调整;
若做加法后 AL中的高半字节 >9或 CF= 1,则
AL= AL+ 60H,对高半字节进行调整,并 CF置 1,否则 CF置 0
例题:若 AL= BCD88,BL= BCD49,求两数之和。运算过程为:
ADD AL,BL
DAA
1000 1000 … 88
0100 1001 … 49+
1101 0001 … AF=1+
0000 0110 … 加 6调整
1101 0111 … 调整后高半字节 >9
0110 0000 … 加 60H调整
0011 0111
结果为 AL= BCD37,CF=1
+
(3)AAS减法的 ASCII调整指令功能:在用 SUB或 SBB指令对两个非压缩十进数或以 ASCII码表示的十进制数进行相减后,对 AL中所得的结果进行调整,在 AL
中得到一个正确的非压缩十进制数之差。如有借位,则 CF= 1。
AAS指令必须紧跟在 SUB和 SBB指令之后。
调整过程为:若 AL寄存器的低 4位 >9或 AF= 1
AL= AL- 6;
将 AL寄存器高 4位清零
AH= AH-1;否则不需要调整。
例题:设 AL= BCD3,CL= BCD8,求两数之差。
SUB AL,CL
AAS
0000 0011 … BCD3
0000 1000 … BCD8-
1111 1011 … 低 4位 >9-
0000 0110 … 减 6调整
1111 0101
0000 1111 … 清高 4位∧
0000 0101 … AL= 5
结果为 5,CF= 1有借位
(4)DAS减法的十进制调整指令功能:在用 SUB或 SBB指令对两个压缩十进数进行相减后,对
AL中所得的结果进行调整,在 AL中得到一个正确的压缩十进制数。同样需要对 AL中的高半字节和低半字节进行调整。
例题:设 AL= BCD56,CL= BCD98,求两数之差。
SUB AL,CL
DAS
调整过程为:
若 AL中的低 4位 >9或 AF= 1,则
AL= AL- 6,AF置 1;
若 AL中的高半字节 >9或 CF= 1,则
AL= AL- 60H,CF置 1。
0101 0110 … BCD56
1001 1000 … BCD98-
1011 1110 … 低 4位 >9,CF= AF= 1-
0000 0110 … 减 6调整
1011 1000 … 高 4位 >9
0110 0000 … 减 60H调整∧
0101 1000 … BCD58
结果为 AL= BCD58,CF= 1 表示有借位
(5)AAM乘法的 ASCII调整指令调整过程为:把 AL的内容除以 10,商放在 AH中,余数放在 AL中。
例题:求两个非压缩十进制数 09和 06之乘积,可以实现为:
MOV AL,09H
MOV BL,06H
MUL BL ; AL =36H
AAM ;调整得 AH= 05H,AL= 04H
功能:对存在在 AL中的两个非压缩十进制数相乘的乘积进行十进制的调整,使得在 AX中得到正确的非压缩十进制数的乘积,
高位放在 AH中,低位放在 AL中。两个 ASCII码数相乘之前,必须先屏蔽掉每个数字的高半字节,从而使每个字节包含一个非压缩十进制数 (BCD数 ),再用 MUL指令相乘,乘积放到 AL中,
然后再用 AAM进行调整。
(6)AAD除法的 ASCII调整指令功能:做除法之前,把 BCD码转换成二进制数调整方式:
AL= AH× 10+ AL
AH= 00
6,算术运算指令对标志位的影响总结
( 1)加、减、乘、除指令均影响 6个标志位 CF,OF,PF,SF、
ZF和 AF。
( 2)加 1、减 1指令影响 除进位标志 CF以外 的 5个标志位 AF,OF、
PF,SF和 ZF。
( 3)取补指令( NEG)的 CF=1,影响其余的 5个标志位 AF,OF、
PF,SF和 ZF。
( 4)比较指令( CMP)影响 6个标志位 CF,OF,PF,SF,ZF和
AF。
( 5)压缩的 BCD码加、减法调整指令影响 除进位标志 OF以外 的 5
个标志位 AF,CF,PF,SF和 ZF。
( 6)非压缩的 BCD码加、减法调整指令影响 2个标志位 CF和 AF;
其余标志没有意义。
( 7)非压缩的 BCD码乘、除法调整指令影响 3个标志位 PF,SF和
ZF; CF,AF,OF没有意义。
3.3.3 逻辑运算和移位指令逻辑运算和移位指令包括逻辑运算、移位和循环移位指令三类指令。
1.逻辑运算指令功能,执行逻辑运算。与、或、非、异或等逻辑运算。
(1) 逻辑与指令 AND
格式,AND OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) ∧ ( OPRD2 )
功能,对两个操作数进行按位的逻辑“与”运算,结果送回目的操作数。
规定:
①目的操作数 OPRD1可以是累加器 AX( AL)、任一通用寄存器 reg,或内存单元 mem(所有寻址方式)。源操作数 OPRD2可以是立即数 data、寄存器 reg,也可以是内存单元 mem (所有寻址方式) 。
② 8086/8088的 AND指令可以进行字节操作,也可以进行字操作。
③利用与指令可实现屏蔽某个数据的某些位(使一个字或字节中的某些位清 0,而其余位不变),提取某些位或拆字。
例如,AND AL,0FH ;可完成拆字的动作,屏蔽高 4位。
(2) 逻辑或指令 OR
格式,OR OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) ∨ ( OPRD2 )
功能,对指定的两个操作数进行逻辑“或”运算。结果送回目的操作数。
规定,基本同 AND。利用或指令可实现置位某个数据的某些位
(使一个字或字节中的某些位置 1,而其余位不变)拼字。
例如,AND AL,0FH
AND AH,0F0H
OR AL,AH ; 完成拼字的动作
OR AX,0FFFH;将 AX低 12位置 1
OR BX,BX ; 清相应标志
(3) 逻辑非指令 NOT
格式,NOT OPRD; ( OPRD ) ← ( OPRD )
功能,对操作数求反,然后送回原处,操作数可以是寄存器 reg
或存储单元内容 mem。 此指令对标志无影响 。
规定,非指令常用于使某个数取反,或取反后 +1而得补码 。
例如,NOTAL
(4)逻辑异或指令 XOR
格式,XOR OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) ∨ ( OPRD2 )
功能,对两个指定的操作数进行,异或,运算,结果送回目的操作数 。
规定:
① 目的操作数 OPRD1可以是累加器 AX( AL),可以是任一个通用寄存器 reg,也可以是一个存储单元 mem(全部寻址方式 )。
源操作数可以是立即数 data,寄存器 reg,也可以是存储单元
mem(所有寻址方式 )。
② 利用异或指令可实现某个寄存器清 0,或使目的操作数的某些位取反 ( 使一个字或字节中的某些位取反,而其余位不变 ) 。
例如,XOR AL,AL ;使 AL清 0
XOR SI,SI ;使 SI清 0
XOR CL,0FH ;使低 4位取反,高 4位不变
(5)测试指令 TEST
格式,TEST OPRD1,OPRD2 ; ( OPRD1) ∧ ( OPRD2 )
功能,完成与 AND指令相同的操作 ( 与操作 ),结果反映在标志位上,但并不送回 ( 结果不保存 ) 。
功能,通常使用它进行测试 。 测试目的操作数的某些位是 1还是 0,
用 ZF标志判断 。
① 判断目的操作数的某些位是否为 1的方法:
TEST AL,01H; ( AL ) ∧ ( 01H )
若 AL0=0,则 ZF=1;若 AL0=1,则 ZF=0。
② 判断目的操作数的某些位是否为 0的方法:
TEST AL,0FH; ( AL ) ∧ ( 0FH )
若 AL0~3=0000B,则 ZF=1;若 AL0≠0000B,则 ZF=0。
例如,若要检测 AL中的最低位是否为 1,为 1则转移 。 可用以下指令:
TEST AL,01H
JNZ THERE
……
THERE:
注,① 逻辑运算类指令中,源操作数为 reg,mem,data;目的操作数为 reg,mem( NOT指令只有一个操作数 ) 。 单操作数指令 NOT的操作数不能为立即数 。 双操作数逻辑指令中,必须有一个操作数为寄存器寻址方式,且目的操作数不能为立即数 。
② 逻辑运算类指令对标志位的影响情况如下,NOT不影响标志位,其它四种指令将使 CF=OF=0,AF无定义,而 SF,ZF和 PF
则根据运算结果而定 。
③ 利用 与指令 可实现屏蔽某个数据的某些位 ( 使一个字或字节中的某些位清 0,而其余位不变 ),提取某些位或拆字 。 利用 或指令可实现置位某个数据的某些位 ( 使一个字或字节中的某些位置 1,
而其余位不变 ) 拼字 。 非指令 常用于使某个数取反,或取反后 +1而得补码 。 利用 异或指令 可实现某个寄存器清 0,或使目的操作数的某些位取反 ( 使一个字或字节中的某些位取反,而其余位不变 ) 。
通常使用 测试指令 进行测试 。 测试目的操作数的某些位是 1还是 0,
用 ZF标志判断 。
2,移位指令格式,操作码 OPRD,CNT
功能,将 OPRD的内容移位 CNT次 。
规定,① OPRD可以是累加器 AX( AL),可以是任一个通用寄存器 reg,也可以是一个存储单元 mem;其寻址方式可以采用除立即寻址外的任何寻址方式 。
② CNT=1时,只移 1位; CNT>1时,可将指令格式中的 CNT
改为 CL寄存器,并在移位指令前将移位次数预先送入 CL寄存器中 。
③ 影响 CF,SF,ZF,PF标志,在移 1位时,还影响 OF标志 。
④ 算术移位助记符为 SA,逻辑移位为 SH,循环移位为 RO,
带进位位的循环移位为 RC。 R为右移,L为左移 。
⑤ 算术移位适用于带符号数的? 2,/2。 逻辑移位适用于无符号数的 × 2,÷ 2。
( 1) 算术 /逻辑移位指令
① 算术左移或逻辑左移指令,SAL/ SHL OPRD,M ;
② 算术右移指令,SAR OPRD,M
③ 逻辑右移指令,SHR OPRD,M
规定,① M是移位次数,可以是 1或寄存器 CL
② 算术 /逻辑移位指令可以对寄存器或存储器单元进行指定的移位,可以进行字节或字操作;可以一次只移 1位,也可以移位由寄存器 CL中的内容规定的次数 。
算术 /逻辑移位 指令操作示意图如下:
( 2) 循环移位指令循环左移,ROL OPRD,M ;
循环右移,ROR OPRD,M ;
带进位循环左移,RCL OPRD,M ;
带进位循环右移,RCR OPRD,M ;
前两条循环指令,未把标志位 CF包含在循环的环中,后两条把标志位 CF包含在循环的环中,作为整个循环的一部分 。 循环移位指令操作示意图如下:
功能,循环指令可以对字节或字进行操作 。 操作数可以是寄存器
reg,也可以存储器单元 mem。 可以是循环移位一次,也可以循环移位由 CL的内容所决定的次数 。
左移一位,只要左移以后的数未超出一个字节或一个字的表达范围,则原数的每一位的权增加了一倍,相当于原数乘 2。 右移一位相当于除以 2。
例如,乘 10的操作在数的输入输出过程中乘 10的操作是经常要进行的 。 而
X× 10=X× 2+X× 8,也可以采用移位和相加的办法来实现 × 10。
为保证结果完整,先将 AL中的字节扩展为字 。
MOV AH,0
SAL AX,1 ; X × 2
MOV BX,AX ;移至 BX中暂存
SAL AX,1 ; X × 4
SAL AX,1 ; X × 8
ADD AX,BX ; X × 10
3.3.4 串操作类指令 ( 简单介绍 )
串操作类指令就是用一条指令实现对一串字符或数据 ( 数据串 ) 的操作 。 这些数据串可以是字节串,也可以是字串 。
特点:
① 串操作类指令是唯一的一组 源和目的操作数均在存储单元的指令 。 源串在数据段,目的串在附加段 。 各指令所使用的默认寄存器是:
源串地址 DS,SI
目的串地址 ES,DI
字串长度 CX
存取或搜索的默认值 AL
② 串操作时,地址的修改往往与方向标志 ( DF) 有关 。
DF=1,SI,DI作自动减量 ( 自动 -1) 修改;
DF=0,SI,DI作自动增量 ( 自动 +1) 修改 。
③ 建立方向标志 ( FR) 的方法:
可用传送指令硬置 FR,也可以用建立方向标志的指令:
CLD ; DF=0
STD ; DF=1
④ 任何一个串操作指令均可在指令前面加上一个重复操作作为前缀,于是之仍旧重复执行,直至 CX,ZF满足要求为止 。
1,重复指令前缀串操作类指令可以与重复指令前缀配合使用 。 从而使操作得以重复进行,及时停止 。 重复指令前缀的几种形式见下表所示 。
汇编格式重复前缀 执行过程影响指令
REP
① 若 (CX)= 0,则退出; ② CX=CX-1;
③执行后续指令; ④重复① ----③
MOVS,
STOS
LODS
REPE/
REPZ
① 若 (CX)= 0或 ZF=0,则退出; ② CX=CX-1; ③ 执行后续指令; ④重复① ----③
CMPS
SCAS
REPNE/
REPNZ
① 若 (CX)= 0或 ZF=1,则退出; ② CX=CX-1; ③执行后续指令; ④重复① ----③
CMPS
SCAS
2,串指令 ( 阅读教材 P97----100)
串指令共有五种,具体见下表。
串操作指令功能 指令格式 执行操作串传送 MOVS DST,SRC
MOVSB
MOVSW
由操作数说明是字节或字操作;其余同 MOVSB或 MOVSW
[(ES,DI)]←[(DS,SI)]; SI=SI± 1,DI=DI± 1; REP控制重复前两步
[(ES,DI)]←[(DS,SI)]; SI=SI± 2,DI=DI± 2; REP控制重复前两步串比较 CMPS DST,SRC
CMPSB
CMPSW
由操作数说明是字节或字操作;其余同 CMPSB或 CMPSW
[(ES,DI)]- [(DS,SI)]; SI=SI± 1,DI=DI± 1;重复前缀控制前两步
[(ES,DI)]- [(DS,SI)]; SI=SI± 2,DI=DI± 2;重复前缀控制前两步串搜索 SCAS DST
SCASB
SCASW
由操作数说明是字节或字操作;其余同 SCASB或 SCASW
AL- [(ES,DI)]]; DI=DI± 1;重复前缀控制前两步
AX- [(ES,DI)]; DI=DI± 2;重复前缀控制前两步存串 STOS DST
STOSB
STOSW
由 操作数说明是字节或字操作;其余同 STOSB或 STOSW
AL→[(ES,DI)]]; DI=DI± 1;重复前缀控制前两步
AX→[(ES,DI)]; DI=DI± 2;重复前缀控制前两步取串 LODS SRC
LODSB
LODSW
由操作数说明是字节或字操作;其余同 LODSB或 LODSW
[(DS,SI)]]→ AL; SI=SI± 1;重复前缀控制前两步
[(DS,SI)]→ AX; SI=SI± 2;重复前缀控制前两步
MOVS指令的功能把数据段中由 SI间接寻址的一个字节 (或一个字 )传送到附加段中由 DI间接寻址的一个字节单元 (或一个字单元 )中去,然后,根据方向标志 DF及所传送数据的类型 (字节或字 )对 SI及 DI进行修改,在指令重复前缀 REP的控制下,可将数据段中的整串数据传送到附加段中去 。
[例 ] 在数据段中有一字符串,其长度为 17,要求把它们传送到附加段中的一个缓冲区中,其中源串存放在数据段中从符号地址 MESS1开始的存储区域内,
每个字符占一个字节; MESS2为附加段中用以存放字符串区域的首地址 。
实现上述功能的程序段如下:
LEA SI,MESS1 ;置源串偏移地址
LEA DI,MESS2 ;置目的串偏移地址
MOV CX,17 ;置串长度
CLD ;方向标志复位
REP MOVSB ;字符串传送其中,最后一条指令也可写成
REP MOVS ES,BYTE PTR[DI],DS,[SI]
或 REP MOVS MESS2,MESS1
CMPS指令的功能把数据段中由 SI间接寻址的一个字节 (或一个字 )与附加段中由 DI间接寻址的一个字节 (或一个字 )进行比较操作,使比较的结果影响标志位,然后根据方向标志 DF及所进行比较的操作数类型 (字节或字 )对 SI及 DI进行修改,在指令重复前缀 REPE/REPZ或者 REPNE/REPNZ的控制下,可在两个数据串中寻找第一个不相等的字节 (或字 ),或者第一个相等的字节 (或字 )。
[例 ] 在数据段中有一字符串,其长度为 17,存放在数据段中从符号地址
MESS1开始的区域中;同样在附加段中有一长度相等的字符串,存放在附加段中从符号地址 MESS2开始的区域中,现要求找出它们之间不相匹配的位置 。
实现上述功能的程序段如下;
LEA SI,MESS1 ;装入源串偏移地址
LEA DI,MESS2 ;装入目的串偏移地址
MOV CX,17 ;装入字符串长度
CLD ;方向标志复位
REPE CMPSB
上述程序段执行之后,SI或 DI的内容即为两字符串中第一个不匹配字符的下一个字符的位置 。 若两字符串中没有不匹配的字符,则当比较完毕后,
CX= 0,退出重复操作状态 。
SCAS指令的功能用由指令指定的关键字节或关键字 (分别存放在 AL及 AX 寄存器中 ),与附加段中由 DI间接寻址的字节串 (或字串 )中的一个字节 (或字 )进行比较操作,使比较的结果影响标志位,然后根据方向标志 DF及所进行操作的数据类型 (字节或字 ) 对 DI进行修改,在指令重复前缀 REPE/REPZ或 REPNE/REPNZ的控制下,可在指定的数据串中搜索第一个与关键字节 (或字 )匹配的字节 (或字 ),或者搜索第一个与关键字节 (或字 )不匹配的字节 (或字 )。
[例 ] 在附加段中有一个字符串,存放在以符号地址 MESS2开始的区域中,长度为 17,要求在该字符串中搜索空格符 (ASCII码为 20H)。
实现上述功能的程序段如下:
LEA DI,MESS2 ;装入目的串偏移地址
MOV AL,20H ;装入关键字节
MOV CX,17 ;装入字符串长度
REPNE SCASB
上述程序段执行之后,DI的内容即为相匹配字符的下一个字符的地址,
CX中是剩下还未比较的字符个数 。 若字符串中没有所要搜索的关键字节 (或字 ),
则当查完之后 (CX)= 0退出重复操作状态 。
STOS指令的功能把指令中指定的一个字节或一个字 (分别存放在 AL及 AX寄存器中 ),传送到附加段中由 DI间接寻址的字节内存单元 (或字内存单元 )中去,然后,根据方向标志 DF及所进行操作的数据类型
(字节或字 )对 DI进行修改操作 。 在指令重复前缀的控制下,可连续将 AL( AX) 的内容存入到附加段中的一段内存区域中去,该指令不影标志位 。 例 要对附加段中从 MESS2开始的 5个连续的内存字节单元进行清 0操作,可用下列程序段实现:
LEA DI,MESS2 ;装入目的区域偏移地址
MOV AL,00H ;为清零操作准备
MOV CX,5 ;设置区域长度
REP STOSB
LODS指令的功能从串中取指令实现从指定的字节串 (或字串 )中读出信息的操作 。
[例 ] 比较 DEST和 SOURCE中的 500个字节,找出第一个不相同的字节,如果找到,则将 SOURCE中的这个数送 AL中 。
CLD
LEA DI,ES,DEST
LEA SI,SOURCE
MOV CX,500
REPE CMPSB
JCXZ NEXT ;CX=0则转移
MATCH,DEC SI
MOV AL,BYTE PTR[SI]
NEXT,……
3.3.5 控制转移类指令( P100)
转移类指令可改变 CS与 IP的值或仅改变 IP的值,以改变指令执行的顺序。
控制转移指令,凡是能改变指令执行顺序的指令统称为控制转移指令。
控制转移指令分类,共分六类,无条件转移指令、子程序调用和返回指令、条件转移指令、循环控制指令、中断指令、处理器控制命令。
1.程序转移的地址( P100)
程序的寻址是由 CS和 IP完成的,为使程序转移到一个新的地址执行,同时改变 CS和 IP或只改变 IP的内容均可。
可直接转移(转移的目的地址直接出现在指令的机器码中)。
也可间接转移(转移的目的地址间接存储于某一个寄存器或某一个内存变量中)。
( 1)段间转移、段间调用同时改变 CS和 IP内容。将下一条指令的 IP入栈( SP-2),CS
入栈( SP-2),返回时出栈。
( 2)段内转移、段内调用只改变 IP的内容,将下一条指令的 IP入栈( SP-2),返回时出栈 。可分为 16位偏移量 NEAR和 8位偏移量 SHORT,16位偏移量适用于无条件转移指令和条件转移指令; 8位偏移量适用于条件转移指令,范围为 -128 ---- +127。
注,段间转移、段间调用、段内转移、段内调用的 CS和 IP的入栈和出栈 是由机器自动完成的。
2.无条件转移指令( P101)
无条件转移指令可以转移到存储器的任何程序段。
格式,JMP [转移方式 ]OPRD
功能,转移到 OPRD所指向的存储器单元处执行程序。
规定,OPRD可为除立即数外的各种寻址方式。
( 1)段内直接短转移指令格式,JMP SHORT OPRD;( IP) ← ( IP) + OPRD
规定,OPRD为 8位地址偏移量,为符号地址(标号)。由
SHORT指出,范围为 -128 ---- +127。
( 2)段内直接近转移指令格式,JMP NEAR PTR OPRD;( IP) ← ( IP) + OPRD
规定,OPRD为 16位地址偏移量,为符号地址(标号) 。由
NEAR指出,NEAR可省略( 指令可写成 JMP OPRD )。目的地址与 JMP指令应处于同一地址段范围之内。
( 3)段内间接转移指令格式,JMP WORD PTR OPRD;( IP) ← [EA]
规定,OPRD可为除立即数外的各种寻址方式。若 OPRD为 16位寄存器,则( IP) ← ( reg);若 OPRD为存储器中的一个字,则
( IP) ← ( add+1) ( add)。如:
JMP WORD PTR[BX]; ( IP ) ← (( DS)? 16 +( BX))
JMP WORD PTR BX ; ( IP ) ← ( BX)
( 4)段间直接(远)转移指令格式,JMP FAR PTR OPRD;( IP) ← OPRD的段内偏移地址
( CS) ← OPRD所在的段地址规定,OPRD为直接寻址方式。
( 5)段间间接转移指令格式,JMP DOWRD PTR OPRD; ( IP) ← [EA]
( CS) ← [EA+2]
3.子程序调用和返回指令 ( P105)
( 1)子程序调用指令 CALL
CALL指令用来调用一个过程或子程序 。 由于过程或子程序有段间 (即远程
FAR)和段内调用 ( 即近程 NEAR) 之分 。 所以 CALL也有 FAR和 NEAR之分 。
因此返回指令 RET也分段间与段内返回两种 。
格式,CALL 子程序名 DST
段内调用,CALL NEAR PTR OPRD ;
( SP) ← ( SP-2),(( SP) +1) ( SP)) ← ( IP),
( IP ) ← 子程序 DST的地址 ( 即,IP+16位位移量 )
规定,CALL指令首先将当前 IP内容压入堆栈 。 当执行 RET指令而返回时,从堆栈中取出一个字放入 IP中 。
段间调用,CALL FAR PTR OPRD ;
( SP) ← ( SP-2),(( SP) +1),( SP)) =( CS ) ;
( SP) ← ( SP-2),(( SP) +1),( SP)) =( IP ) ;
( IP ) =[EA]; ( CS ) =[EA+2]
规定,CALL指令先把 CS压入堆栈,再把 IP压入堆栈。当执行
RET指令而返回时,从堆栈中取出一个字放入 IP中,然后从堆栈中再取出第二个字放入 CS中,作为段间返回地址。
( 2)子程序返回指令 RET
格式,RET ;( IP ) ← (( SP) +1,SP),
( SP ) ← ( SP) + 2
RET n ; ( IP ) ← (( SP+1),SP),
( SP ) ← ( SP+2 ),
返回后 ( SP ) ← ( SP+ n )
规定,RET n 指令要求 n 为 0----0FFFFH范围内的偶数,当
RET正常返回后,再做 SP=SP+n操作。 相当于子程序返回后,
将栈中的 n个单元腾出来了。主要用于主程序为某个子程序提供一定的参数或参数地址。
4.条件转移指令( P109)
8086的条件转移指令是根据标志寄存器中各标志位的状态,
决定程序是否进行转移 。 条件转移指令的目的地址必须在现行的代码段 (CS)内,并且以当前指令指针寄存器 IP内容为基准,
其位移必须在十 127~— 128的范围之内 。
格式,指令助记符 目的地址功能,当条件满足时,转到目的地址处继续执行 。
规定,对于无符号数,A----高于,B----低于,E----等于 。
对于带符号数,G ----大于,L----小于,E----等于 。
指令 JG( 大于 ) 与 JNLE( 不小于 ) 是等同的,同理,
JG/JNLE,JL/JNGE,JGE/JNL,JLE/JNG,JA/JNBE,
JB/JNAE,JAE/JNB,JBE/JNA均是等同的 。
( 1) 标志位转移指令 ( J__/JN__) ( P110表 3-11)
结果为零 /结果不为零转移,JZ( /JE) /JNZ( /JNE) OPRD
结果为负数 /结果为正数转移,JS/JNS OPRD
结果奇偶校验为偶 /结果奇偶校验为奇转移:
JP( /JPE ) /JNP( /JPO ) OPRD
结果溢出 /结果不溢出转移,JO/JNO OPRD
结果有进位 ( 借位 ) /结果无进位 ( 借位 ) 转移:
JC/JNC OPRD
( 2) 不带符号数比较转移指令 ( P110表 3-12,注意条件 )
高于或不低于等于转移,JA/JNBE OPRD (CF∨ ZF=0)
高于等于或不低于转移,JAE/JNB OPRD (CF=0)
低于或不 高 于等于转移,JB/JNAE OPRD (CF=1)
低于等于或不 高 于转移,JBE/JNA OPRD (CF∨ ZF=1)
( 2) 带符号数比较转移指令大于或不小于等于转移,JG/JNLE OPRD ((SF⊕ OF) ∨ ZF=0)
大于等于或不低于转移,JGE/JNL OPRD (SF⊕ OF=0)
小于或不大于等于转移,JL/JNGE OPRD (SF⊕ OF=1)
小于等于或不大于转移,JLE/JNG OPRD ((SF⊕ OF) ∨ ZF=1)
( 3) 测试转移指令
CX=0 时转移,JCXZ OPRD
注,条件转移指令是根据两个数的比较结果或某些标志位的状态来决定转移的。在条件转移指令中,有的根据对符号数进行比较和测试的结果实现转移。这些指令通常对溢出标志位 OF和符号标志位 SF进行测试。对无符号数而言,这类指令通常测试标志位
CF。对于带符号数分大于、等于、小于 3种情况;对于无符号数分高于、等于、低于 3种情况。在使用这些条件转移指令时,一定要注意被比较数的具体情况及比较后所能出现的预期结果。
5,循环控制指令( P112)
对于需要重复进行的操作,微机系统可用循环程序结构来进行,8086系统为了简化程序设计,设置了一组循环指令,这组指令主要对 CX或标志位 ZF进行测试,确定是否循环 。
( 1) LOOP OPRD;
( CX ) ← ( CX ) -1,若 CX≠ 0,则循环,否则顺序执行 。
( 2) LOOPNZ/LOOPNE OPRD;
( CX ) ← ( CX ) -1,若 CX≠ 0 且 ZF=0,则循环,否则顺序执行 。
( 3) LOOPZ/LOOPE OPRD;
( CX ) ← ( CX ) -1,若 CX≠ 0 且 ZF=1,则循环,否则顺序执行 。
( 4) JCXZ OPRD;
( CX ) ← ( CX ) -1,若 CX=0,则循环,否则顺序执行 。
6,中断指令( P115)
( 1) INT n ;
( SP) ← ( SP) -2,( ( SP) +1,( SP) ) ← ( FR),FR入栈
( SP) ← ( SP) -2,( ( SP) +1,( SP) ) ← ( CS),CS入栈
( SP) ← ( SP) -2,( ( SP) +1,( SP) ) ← ( IP),IP入栈
( IP) ← ( n? 4),( CS) ← ( n? 4+2)
n:中断类型号,范围为 0----255。有关中断类型号、中断向量在第 5章中断方式中介绍。
( 2) INTO
功能,INTO放在算术运算指令之后,若算术运的 OF=1,则执行溢出中断(内部中断,中断类型号为 4,同 INT 4),否则继续执行。
( 3) IRET
( IP) ← ( ( SP) +1,( SP) ),( SP) ← ( SP) +2,IP出栈
( CS) ← ( ( SP) +1,( SP) ),( SP) ← ( SP) +2,CS出栈
( FR) ← ( ( SP) +1,( SP) ),( SP) ← ( SP) +2,FR出栈功能,中断服务子程序返回指令,是中断服务子程序的最后一条指令,功能类似于子程序返回指令 RET。
7,处理器控制指令( P117)
处理器控制指令只完成简单的控制功能,无操作地址,又称为无地址指令。
( 1)标志操作指令功能,只对标志位(主要有 CF,DF和 IF三个标志)进行操作,只影响相应的一个标志。
规定,清标志位为 CL,置标志位为 ST,再加上标志的第一个字母。
相应的指令如下:
清进位标志,CLC ; ( CF ) ← 0
置进位标志,STC; ( CF ) ← 1
进位标志取反,CMC; ( CF ) ← ( CF )
清方向标志,CLD; ( DF ) ← 0
置方向标志,STD; ( DF ) ← 1
关中断标志,CLI; ( IF ) ← 0,不允许中断开中断标志,STI; ( IF ) ← 1,允许中断
( 2)处理器外部同步命令处理器外部同步命令用以控制处理器的工作状态,均不影响标志位 。具体指令如下:
暂停指令,HLT
处理器处于什么也不做的暂停状态,可由中断请求,复位等唤醒继续执行 。
等待指令,WAIT
使处理器处于等待状态,CPU每隔 4个时钟周期测试一次 TEST
引脚线 ( 23脚 ),直至 TEST引脚线为有效低电平时,CPU才脱离等待状态 。
交权指令,ESC
CPU将控制权交给其他协处理器,使协处理器从系统指令流中取得指令 。
总线封锁指令,LOCK
可放在任一条指令前作为前缀,它使 CPU在执行下一条指令期间发出总线封锁信号 ( LOCK ),将总线封锁,其它的主设备不能控制总线 。 即不能访问存储器和外设 。
空操作指令,NOP
常用于程序的延时和调试 。
到此为止,我们已把 8086的指令系统介绍完了 。
8,指令的执行时间和软件延时( P119)
每条指令执行时都需要几个时钟周期。 ( P119表 3-14,3-15)
8086的时钟周期:主频率的倒数。
例,延时 10mS的程序。设 CPU的主频为 5MHz。
分析,延时程序的目的是使 CPU执行一段程序,没有具体的执行结果,但需要这段程序的执行时间。如:等待有效信号的出现,
键盘的去抖动等。
延时程序一般通过循环程序实现。
需要了解:
时钟周期 =主频率的倒数 =1/( 5× 10-6) =0.2μs
指令的时钟周期数:
MOV CX,N 4
LOOP AA 循环时为 17,不循环时为 5
NOP 3
RET 段内 16,段间 24
延时 10ms需要的时钟周期数 = 10ms/ 0.2μs=50000
解:编写延时程序:
DELAY10,MOV CX,N 4
DLY1,NOP 3 × N
LOOP DLY1 17 × ( N-1) + 5
RET 16
应该有 50000=4+ 3 × N+ 17 × ( N-1) + 5+16,才能实现要求的延时。则:
N=2500=09C4H
实际的延时程序如下:
DELAY10,MOV CX,09C4H
DLY1,NOP
LOOP DLY1
RET
思考:
这个延时程序是否存在误差,如何消除误差?
作业:
P121
1,2,6,10,13,15
3.1 8086/8088寻址方式
3.2 指令的机器码表示方法
3.3 8086指令系统
1,指令,让计算机完成某种操作的命令称为指令。
2,指令系统,指令的集合即为指令系统。
3,指令的一般格式:
[标号,] 操作码 [操作数 ] [,操作数 ] ; [注释 ]
计算机中的指令由标号、操作码字段和操作数字段组成。
[ ],任选项。
标号字段,是一个任选字段,性质为符号偏移量,一般用于标记跳转指令的目的地址.在汇编过程中标号会被替换为一个 16位的数值偏移量.标号必须位于语句开头,结尾必须使用冒号。
操作码 字段,也称为 指令助记符,指令助记符是必不可少的,指计算机所要执行的操作,或称为指出操作类型,是一种助记符。
操作数 字段,指在指令执行操作的过程中所需要的操作数。该字段除可以是操作数本身外,也可以是操作数地址或是地址的一部分,还可以是指向操作数地址的指针或其它有关操作数的信息。
注释字段,是一个任选字段,用于说明程序片段或指令的功能,
汇编过程中不处理这样的字段,它只是用于提高源程序的可读性.注释必须使用分号作为开始。注释是对该条或该段程序的解释,可选项。
不同的计算机有不同的指令系统,汇编语言的指令语句都与机器指令一一对应,汇编语言通过汇编程序将其翻译成机器指令代码(目标代码),让 CPU执行某种操作。
3.1 8086/8088寻址方式寻址方式,指令中用于说明操作数所在地址的方法,或者说是为获取实际操作数地址而采取的方法称为寻址方式 。 8086/ 8088的基本寻址方式有七种 。
3.1.1 立即寻址
3.1.2 直接寻址
3.1.3 寄存器寻址
3.1.4 寄存器间接寻址
3.1.5 寄存器相对寻址(直接变址寻址、变址寻址)
3.1.6 基址变址寻址
3.1.7 相对基址变址寻址
3.1.1 立即寻址定义,操作数直接由指令提供的寻址方式称为 立即寻址方式 。
在立即寻址方式中所提供的操作数直接包含在指令中 。 它紧跟在操作码的后面,与操作码一起放在代码段区域中 。 如图所示 。
例如,MOV AX,3000H
立即数,直接由指令提供的具体操作数称为立即数 。
特点:
( 1) 立即数可以是 8位的,也可以是 16位的 。 若是 16位的,则存储时低位在前,高位在后 。 只能是整数,不能是小数,变量或其它数据类型 。
( 2) 立即数只能作为源操作数,立即寻址主要用来给寄存器或存储器赋初值 。
( 3)速度快(操作数直接由指令中获得,不需要运行总线周期)
( 4)立即数作为指令操作码的一部分与操作码一起放在代码段区域中。
( 5)指令的长度较长,灵活性较差。
【 例 3.1】 MOV AX,10
执行后 ( AX) =?
其中:源操作数为立即寻址方式,立即数为 10,存放在指令的下一单元 。
图形表示:
执行,10→AX
执行后,( AX) =000AH
3.1.2 直接寻址定义,操作数的有效地址 EA直接由指令直接提供的寻址方式称为直接寻址方式 。
在直接寻址方式中操作数地址的 16位偏移量直接包含在指令中,它与操作码 一 起存放在代码段区域,操作数一般在数据段区域中,它的地址为数据段寄存器 DS加上这 16位地址偏移量 。
如图所示 。
例如,MOV AX,DS,[2000H];
特点:
( 1) 如果指令中没有指明操作数存放在哪一段,则系统默认为数据段 DS。 如上例可写成,MOV AX,[2000H]
( 2) 操作数的有效地址与操作码 一 起存放在代码段区域,操作数一般在数据段区域中 。
( 3) 直接寻址是对存储器进行访问时可采用的最简单的形式 。
这种寻址方法是以数据段的地址为基础,可在多达 64KB的范围内寻找操作数 。
( 4) 操作数的实际地址为数据段寄存器 DS左移 4位加上操作数的有效地址 ( 16位地址偏移量 ) 16位地址偏移量 。
( 5) 段超越前缀,如果要对除 DS以外的其他段寄存器 ( 代码段,
堆栈段和附加段 ) 所指出的存储区进行直接寻址,应在指令中指定段寄存器 -----段超越前缀 。 如:
MOV AX,[2000H] ;数据段 ( 可省略 DS )
MOV BX,ES,[3000H] ;操作数在附加段 ES ( 不能省略 ES )
( 6) 直接寻址的地址如果是数值地址,则必须用,[ ]”括起来,
以区别立即数 。 允许用 符号地址 ( 即程序中的标号 ) 代替数值地址 。
【 例 3.2】 寄存器和存储器内容为,( AX) =1212H,BUF为数据段定义的变量,其偏移地址是 2000H,( DS) =3000H,( 32000H)
=4545H。
执行指令,MOV AX,BUF
执行后,( AX) =?
图形表示:
执行,( 32000H) → ( AX)
执行后,( AX) =4545H
3.1.3 寄存器寻址定义,操作数直接存放在 CPU的内部寄存器中 ( 如:寄存器 AX、
BX,CX,DX等 ) 的寻址方式称为寄存器寻址方式 。
例如,MOV DS,AX
MOV AL,BH
特点:
( 1)操作数放在 CPU的通用寄存器中。
16位,AX,BX,CX,DX,SI,DI,SP,IP
8位,AH,AL,BH,BL,CH,CL,DH,DL
通常放在 AX,AH,AL中,因为 AX是累加器,结果一般放在 AX
中,这样指令会更短些。
( 2)采用寄存器寻址时,操作就在 CPU内部进行,不需要使用总线周期,速度快。
( 3)一条指令中,既可以对源操作数采用寄存器寻址,也可以对目的操作数采用寄存器寻址,也可二者均采用寄存器寻址。
【 例 3.3】 下列程序执行后,( AX) =?,( BX) =?
MOV AX,1234H
MOV BX,5678H
ADD AX,BX
该程序中 MOV指令为数据传送指令操作符,ADD指令为加法指令操作符,三条指令皆为双操作数指令 。 第一,二条指令 AX,BX
皆为目的操作数地址,为立即数寻址方式 。 第三条指令中,AX为目的操作数地址,BX为源操作数地址 。 源地址和目的地址皆为寄存器寻址方式 。
3.1.4 寄存器间接寻址操作数是在存储器中,但是,操作数的有效地址 EA( 偏移量 )
在以下四个寄存器 SI,DI,BP,BX之一中 。 可以分成两种情况:
( 1) 以 SI,DI,BX间接寻址,则通常操作数在现行数据段区域中,
即数据段寄存器 ( DS) × 16加上 SI,DI,BX中的 16位偏移量,为操作数的地址,
例如,MOV AX,[SI],操作数地址是,( DS) ╳ 16 +( SI)
( 2) 以寄存器 BP间接寻址,则操作数在堆栈段区域中 。 即堆栈段寄存器 ( SS) × 16与 BP的内容相加作为操作数的地址,
例如,MOV AX,[BP],操作数地址是,( SS) ╳ 16 +( BP)
若在指令中规定是段超越的,则 BP的内容也可以与其它的段寄存器相加,形成操作数地址 。
例如,MOV AX,DS,[BP],操作数地址是,( DS) ╳ 16 +( BP)
特点:
( 1)指令中的基址寄存器与段寄存器的配对关系为:
BX,SI,DI----DS,BP----SS
( 2)如果要对其他段寄存器所指出的区域进行寻址,则在指令中应指出指定超越段前缀。
( 3)寄存器间接寻址方式适用于表格处理。执行完一条指令后,
只需修改寄存器的内容( +1,+2,…… )就可取出表格中的相应项。
( 4)间址的寄存器用,[ ]”括起来,以区别寄存器寻址。
AX
AH AL
数据段 物理地址
A 0 H 21000H
50H 20001H
56H 20002H
【 例 3.4】 指令 MOV AX,[BX]
若 ( DS) = 2000H,( BX) = 1000H,
物理地址= 20000H+ 1000H= 21000H。
指令执行前,( AX) = 2030H,( 21000H) = 0A0H,( 21001H)
= 50H,
指令执行后,( AX) = 50A0H,( 21000H) = 0A0H,( 21001H)
= 50H。
指令执行情况如下:
3.1.5 寄存器相对寻址(直接变址寻址、变址寻址)
寄存器相对寻址方式是在指令中给定一个基址寄存器 ( 或变址寄存器 ) 名和一个 8位或 16位的相对偏移量,两者之和作为操作数的有效地址 EA。 对 BX,SI,DI这三个间址寄存器,指示的是数据段中的数据,而用 BP作间址寄存器,则指示的是堆栈段中的数据 。
汇编格式,X[R]( X表示位移量,是 8位或 16位二进制补码表示的有符号数,R表示寄存器 ) 。
功能,操作数存放在存储器,寄存器 R的内容加位移量 X为操作数的偏移地址 EA。
有效地址 EA计算方法如右:
特点:
( 1) SI,DI,BX默认的段寄存器为 DS,BP默认的段寄存器为 SS。
( 2)可以使用段寄存器超越前缀来寻址其他段。
( 3)寄存器相对寻址方式适用于表格处理。表首的地址可设置为偏移量指针,利用修改基址或变址寄存器的内容来获得表格中的内容。
【 例 3.5】 设执行前,( AX) =0040H,( BX) =0030H,( DS)
=2000H,( 20036H) =0050H
执行指令,ADD 6[BX],AX
执行后,( AX) =?,( BX) =?,( DS) =?,( 20036H) =?
图形表示如下:
执行前,( AX) =0040H,( BX) =0030H,( DS) =2000H,
( 20036H) =0050H
执行指令,ADD 6[BX],AX
执行:( 20036H) +( AX) → ( 20036H)
执行后:( AX) =0040H,
( BX) =0030H,
( DS) =2000H,
( 20036H) =0090H。
图形表示如右:
3.1.6 基址变址寻址把 BX和 BP看成是基址寄存器,把 SI,DI看成是变址寄存器,
把一个基址寄存器( BX或 BP)的内容加上一个变址寄存器( SI或
DI)的内容作为操作数的偏移地址。但指令中不能同时出现两个基址寄存器或两个变址寄存器。
操作数在存储器中,其有效地址 EA由 ( 基址寄存器 ) +
( 变址寄存器 ) 形成 。
特点:
( 1) 基址寄存器为 BX时,默认为数据段 DS,基址寄存器为 BP时,
默认为堆栈段 SS;变址寄存器为 SI,DI。
( 2) 可以使用段寄存器超越前缀来寻址其他段 。
( 3) 基址变址寻址方式适用于数组或表格处理 。 首地址可设置在基址寄存器中,变址寄存器用于访问数组中的元素或表格中的内容 。 基址寄存器和变址寄存器均可以修改,非常灵活 。
【 例 3.6】 MOV AL,[BX+ SI]( 或 MOV AL,[BX][SI])
若指令执行前,( DS) = 1000H,( BX) = 0010H,
( SI) = 0002H,( 10012H) = 45H
则 有效地址 EA= ( BX) + ( SI) = 0012H,
实际地址 PA= ( DS) × 10H+ EA= 10012H
指令执行后 ( AL) = 45H。
3.1.7 相对基址变址寻址把 BX和 BP看成是基址寄存器,把 SI,DI看成是变址寄存器,
把一个基址寄存器( BX或 BP)的内容加上一个变址寄存器( SI或
DI)的内容,再加上指令中指定的 8位或 16位偏移量(当然要以一个段寄存器作为地址基准)作为操作数的偏移地址,如图所示。
相对基址变址寻址德表示形式:
6[BX][SI]
或 [BX+6][SI]
或 [BX+6+SI]
其中:方括号 [ ]有相加的含义操作数在存储器中,其有效地址 EA由 ( 基址寄存器 ) + ( 变址寄存器 ) +相对偏移量形成 。
特点,同基址变址寻址方式,比基址变址寻址方式更灵活 。
表 3-1 段寄存器使用的基本约定访问存储器类型 默认段寄存器 可指定段寄存器 段内偏移地址来源取指令码 CS 无 IP
堆栈操作 SS 无 SP
串操作源地址 DS CS,ES,SS SI
串操作目的地址 ES 无 DI
BP用作基址寄存器 SS CS,DS,ES 根据寻址方式求得 有效地址一般数据存取 DS CS,ES,SS 根据寻址方式求得 有效地址注意:
( 1)隐含寻址:操作数隐含在指令中。
如,DA A,操作数隐含在 AL中。
( 2) I/O端口寻址直接 I/O端口寻址:指令中直接提供端口地址。
如,IN AL,60H
间接 I/O端口寻址:指令中直接指出存放端口地址寄存器 DS。
如,MOV DX,303H
IN AL,DX
( 3)一条指令中可以同时存在几种寻址方式。
如,MOV [BX],AL
3.2 指令的机器码表示方法( P65----P70)
阅读:
知识点,汇编语言、机器语言、汇编语言源程序、汇编的方法。
编码方法:了解掌握。
3.3 8086指令系统
8086的指令可以分为五大类
3.3.1 数据传送指令
3.3.2 算术运算指令
3.3.3,逻辑运算和移位指令
3.3.4 字符串处理指令
3.3.5 控制转移指令
3.3.1 传送指令
(阅读教材 P70----P78页的内容)见 P70表 3-3
对标志为的影响,传送指令除标志传送( SAHF,POPF)外,均不影响标志位。
分类,传送指令可分为通用传送指令、堆栈操作指令、交换操作指令,I/O操作指令、目的地址传送指令和标志传送指令六类。
1.通用传送指令一般格式,MOV OPRD1,OPRD2 ;
[目的操作数 OPRD1]← [ 源操作数 OPRD2]
其中,源操作数 OPRD2为,立即数 data、存储器单元地址 mem、
累加器 AX、寄存器 reg、段寄存器 segreg。
目的操作数 OPRD1为,存储器地址 mem、累加器 AX、寄存器 reg、
段寄存器 segreg、指定段寄存器。
功能,完成数据传送 。
规定:
( 1) MOV指令可在 CPU内部寄存器之间或 CPU与存储器之间传送字( 16位)或字节( 8位)数据,但代码段寄存器 CS和指令指针
IP除外。
R←data mem ←data R←R
R← mem mem ←R
segreg( CS,IP除外) ← R或 mem R← segreg
如,MOV AL,BL;
MOV CX,BX;
MOV DS,BX
MOV CL,4
MOV AX,03FFH
MOV SI,057BH
MOV [2000H],25H
MOV [SI],35H
MOV AX,[1000H]
MOV AL,BUFFER; BUFFER为标号
MOV AX,[SI]
MOV [DI],CX
MOV SI,BLOCK[BP]
MOV DS,DATA[SI+BX]
MOV DEST[BP+DI],ES
( 2)立即数不能作为目的操作数,只能作为源操作数。
MOV 1000H,AL; ( ╳ )
( 3) CS,IP不能作为目的操作数。
MOV CS,AX ; ( ╳ )
MOV IP,AX ; ( ╳ )
( 4)除源操作数为立即数外( mem ←data ),两个操作数中必须有一个为寄存器。即不允许在两个存储器单元之间直接传送数据。
MOV [2000H],[1000H] ; ( ╳ )
如需要把地址 (即段内的地址偏移量 )为 AREAl的存储单元的内容,传送至同一段内的地址为 AREA2的存储单元中去,MOV指令不能直接完成这样的传送,但可以 CPU内部寄存器为桥梁来完成这样的传送:
MOV AL,AREAl
MOV AREA2,AL
( 5)通用传送指令 MOV是唯一允许以段寄存器作为操作数的指令,但 不允许通过 MOV指令直接以立即数方式给段寄存器赋值,
不允许在两个段寄存器之间直接传送数据 。可以通过 AX为桥梁来完成这样的传送:
MOV AX,0
MOV DS,AX
( 6) MOV指令不影响标志位。
2,堆栈指令堆栈,在存储器中开辟一段区域,用于存储一些暂时需要保护而以后还要用到数据 ( 如中断现场的保护与恢复,子程序现场的保护与恢复等 ),这个区域称为堆栈 。
堆栈的特点:
堆栈存储数据的原则为后进先出 。
堆栈在存储器中的位置由 SS,SP确定 。 SP指令可由 MOV指令设置 。
堆栈指针 SP在 8086系统中始终指向栈的顶部,即:始终指向最后压入栈中的数据的地址 。
8086系统中栈的操作是以字为单位的 。 执行一次入栈操作,
SP-2,直至 SP=0( SS ) 栈满为止 。 执行一次出栈操作,SP+2。
功能,主要用于保护中间数据,子程序的现场,中断程序的现场等 。
包括入栈 ( PUSH) 和出栈 ( POP) 指令两类 。 仅能进行字运算 。 ( 操作数不能是立即数 )
格式:
⑴ 入栈指令,PUSH OPRD
功能,将数据压入堆栈执行步骤为,先修改堆栈指针 SP,然后将数据压入堆栈 。
SP =SP-2; [SP]=操作数低 8位; [SP+1]=操作数高 8位 。
例如,PUSH BX
执行过程为,SP=SP-1,[SP]=BH; SP=SP-1,[SP]=BL,如图 。
⑵ 出栈指令,POP OPRD
功能,将数据弹出堆栈 。
执行步骤同入栈指令 。 不同的是,先将数据弹出堆栈,然后修改堆栈指针 SP。 ( SP ) = ( SP ) +2。 例如,POP [BX]
规定:
( 1) 堆栈段 SS,栈指针 SP,堆栈只有一个入 /出口 。
( 2) 栈指针 SP在初始化中需要设置 。 在入,出栈操作中,栈指针 SP是自动修改的,以保证 SP始终指向栈顶 。
( 3) 操作数 OPRD可以是 CPU内部的 16位通用寄存器,段寄存器
( CS除外 ) 和内存单元,也可以用除立即寻址外的所有寻址方式,
但不能使立即数 。 入,出栈操作对象必须是 16位数 。
( 4) PUSH,POP指令必须成对使用,在一个程序中不能出现非成对的 PUSH,POP指令 。
3,交换操作指令格式,XCHG OPRD1,OPRD2;
[目的操作数 OPRD1]←→ [ 源操作数 OPRD2]
功能,完成数据交换,把一个字节或一个字的源操作数与目的操作数相交换。
规定:
( 1) 可实现 8位或 16位数据的交换 。 两个操作数的位数必须相同 。
( 2)交换能在通用寄存器与累加器之间、通用寄存器之间、通用寄存器与存储器之间进行。两个操作数中必须有一个为寄存器。
即 不允许在两个存储器单元之间直接交换数据 。
( 3) 段寄存器和立即数不能作为一个操作数 。
( 4) 交换指令 XCHG不影响标志位 。
例如,XCHG AL,CL
XCHG AX,DI
XCHG BX,SI
XCHG AX,BUFFER
XCHG DATA[SI],DH
4,I/O操作指令
I/O操作指令也称为 累加器专用 传送指令,有三种,输入、输出和累加器换码指令(查表指令)指令。
功能,I/O操作指令用于完成累加器( AX/AL)与 I/O端口之间的数据传送功能。
( 1)输入指令 IN
格式,IN AL,PORT ; AL←[PORT] ( B )
IN AX,PORT; AX←[PORT +1][PORT ] ( W )
IN AL,DX ; AL←[DX] ( B )
IN AX,DX ; AX←[DX+ 1][DX] ( W )
其中,PORT 为 8位端口直接地址 。 B为字节操作,W为字操作 。
功能,从 I/O端口输入数据至 AL或 AX。
规定:
输入指令允许把一个字节或一个字由一个输入端口传送到 AL
或 AX中。
当端口地址 ≤ 255时,PORT为 8位端口直接地址。
当端口地址 ≥255时,则必须用 DX间址( 16位端口直接地址)
保存端口地址,这样用 DX作端口寻址最多可寻找 64K个端口。
⑵ OUT 指令格式,OUT PORT,AL; ( AL) → [PORT] ( B )
OUT PORT,AX; ( AX) → [PORT+1][PORT ] ( W )
OUT DX,AL ; ( AL ) → [DX] ( B )
OUT DX,AX ; ( AX) → [DX+1][DX] ( W )
功能,将 AL或 AX的内容输出至 I/O端口 。 该指令将 AL或 AX中的内容传送到一个输出端口 。 其具体 规定 与 IN指令相同 。
注,IN,OUT指令提供了 8位和 16位两种使用方式,选用哪一种,
取决于外设端口的数据总线的宽度。若外设端口的数据总线为 8
位,则只能用 8位指令,使用 AL;若外设端口的数据总线为 16位,
则只能用 16位指令,使用 AX。
( 3)累加器换码指令 XLAT
格式,XLAT ; ( AL ) ← ( ( DS) × 16+ ( BX) +( AL) )
功能,完成一个字节的换码转换 。 主要用于数制转换,函数表查表,代码转换等场合 。
规定,① 寄存器 AL的内容作为某一项到表首的偏移量 ( 256字节的表的下标 ) 。
② 表的基地址在 BX中 ( 表首地址 ) 。
③ 转换后的结果存放在 AL中 。
特点,XLAT指令不影响标志位 。
例如,MOV BX,OFFSET TABLE
MOV AL,8
XLAT ;查表
OUT 40H,AL ; ( AL) = AAH;向 40H口输出 AAH
AAH
TABLE
第 9个字符表长度 256
……
【 例 3.7】 十进制数到共阴极 LED七段码显示段码的转换。
共阳极 LED显示器的段码,0----9分别为,C0,F9H,A4H、
B0H,99H,92H,82H,F8H,80H,90H。
解,设计过程,
( 1)将段码表存到数据段的一片连续的单元中,表首地址
2000H送 BX。
( 2)将待转换的十进制数送 AX。
( 3)换码。
程序,MOV BX,2000H
MOV AL,3
XLAT
5,目的地址传送指令目的地址传送指令共有三条指令
⑴ 取有效地址指令 LEA(Load Effective Address)
格式,LEA OPRD1,OPRD2
或,LEA reg,[add]; ( reg) ← add,add为有效地址功能,把存储器的有效地址 EA送入一个寄存器 reg 。 即把源操作数
OPRD2的 地址偏移量 传送至目的操作数 OPRD1。
规定,① 源操作数必须是一个存储单元地址 。 目的操作数必须是一个 16位的通用寄存器 。
② 传送到 16位的通用寄存器的是存储器的有效地址 EA,而不是该存储单元的内容 。
③ 这条指令通常用于将一个 16位的通用寄存器作为地址指针 。
例,LEA BX,[2728H] ; ( BX ) ← 2728H
LEA BX,[BX+SI] ; ( BX ) ← ( BX+SI )
⑵ 将地址指针装入 DS和另一个寄存器指令 LDS (Load pointer into DS)
格式,LDS OPRD1,OPRD2
或,LDS reg,[add]; ( reg) ← ( add+1 ) ( add)
( DS) ← ( add+3 ) ( add +2 )
功能,把 4字节的地址指针 ( 包括 2字节的段地址和 2字节的偏移量 )
传送到 DS和 reg中,完成一个地址指针的传送 。 指令将段地址送入
DS,偏移量部分送入一个 16位的指针寄存器或变址寄存器 。
规定,① 源操作数可以是一个存储单元地址,或是用通用寄存器作间址的存储单元地址 。 目的操作数必须是一个 16位的通用寄存器 。
② 目的操作数的段地址必须送到 DS 中 。
③ 传送的是存储单元的内容,而不是存储器的有效地址 EA 。
例如,LDS SI,[BX] ;将把 BX所指的 32位地址指针的段地址部分送入 DS,偏移量部分送入 SI。
⑶ 将地址指针装入 ES和另一个寄存器指令 LES (Load pointer into ES)
格式,LES OPRD1,OPRD2
或,LES reg,[add]; ( reg) ← ( add+1 ) ( add)
( ES) ← ( add+3 ) ( add +2 )
规定,这条指令除将地址指针的段地址送入 ES外,其他同 LDS。
例如,LES DI,[BX+COUNT]
如右图所示。
6,标志寄存器传送指令标志寄存器传送指令共有四条指令 。 均影响标志位 。
标志寄存器 FR( 即程序状态字 PSW)
⑴ LAHF ( LOAD AH WITH FLAG)
格式,LAHF; ( AH) ← ( FR ) 0~ 7
功能,将标志寄存器中的 SF(7),ZF (6),AF (4),PF (2)和 CF
(0) ( 即低 8位 ) 传送至 AH寄存器的指定位,空位没有定义 。
⑵ SAHF ( STORE AH WITH FLAG)
格式,SAHF; ( FR) 0~ 7 ← ( AH)
功能,将寄存器 AH的指定位,送至标志寄存器的 SF,ZF,AF、
PF和 CF位 ( 即低 8位 ) 。 根据 AH的内容,影响上述标志位,对
OF,DF和 IF无影响 。
⑶ PUSHF ( PUSH FLAG)
格式,PUSHF;将 FR入栈 。 ( SP) ← ( SP) - 2
(( SP ) +1,( SP )) ← ( FR )
功能,将标志寄存器 FR压入堆栈顶部,同时修改堆栈指针,不影响标志位 。
⑷ POPF ( POP FLAG)
格式,POPF ;将栈顶的内容弹出到 FR中 。
( FR ) ← (( SP ) +1,( SP ))
( SP) ← ( SP) + 2
功能,堆栈顶部的一个字,传送到标志寄存器 FR,同时修改堆栈指针,影响标志位 。
3.3.2 算术运算指令
(阅读教材 P78----P90页的内容)见 P79表 3-6
8086提供加、减、乘、除四种基本算术操作。这些操作都可用于字节或字的运算,也可以用于带符号数与无符号数的运算。 带符号数用补码表示。同时 8086也提供了十进制调整指令,故可以进行十进制算术运算。
参与加、减运算的操作数可如下图所示。
源操作数目的操作数
1,加法指令 (Addition)
⑴ 加法指令 ADD
格式,ADD OPRD1,OPRD2; ( OPRD1 ) ← ( OPRD1) +( OPRD2)
功能,完成两个操作数相加,结果送至目的操作数 OPRD1。
规定,① 源操作数为通用寄存器 reg,存储单元 mem,立即数 data。
② 目的操作数为累加器 AX( AL),任一通用寄存器 reg及存储单元 mem 。
③ 影响 6个标志位 CF,OF,PF,SF,ZF和 AF。
例如,累加器与立即数相加:
ADD AL,30; ( AL) ← ( AL ) +30
通用寄存器与存储单元内容相加:
ADD BX,[3000H];
( BX ) ← ( BX ) +( 3001H ) ( 3000H )
通用寄存器之间内容相加:
ADD DI,CX; ( DI ) ← ( DI ) +( CX )
通用寄存器与存储单元内容相加:
ADD DX,DATA[BX+SI];
( DX) ← ( DX) + (( BX ) +( SI ) + DATA)
存储器操作数与寄存器相加:
ADD BETA[SI],DX;
(( SI ) + BETA ) ← (( SI ) + BETA ) + ( DX)
⑵ 带进位位加法指令 ADC
格式,ADC OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) +( OPRD2 ) +CF
功能,这条指令与 ADD指令类似,区别在于需要加 CF。 ADC指令主要用于多字节运算中 。 与 ADD相同,影响 6个标志位 CF,DF、
PF,SF,ZF和 AF。
【 例 3.8】 若有两个四字节的数,已分别放在自 FIRST和 SECOND
开始的存储区中,每个数占四个存储单元,结果放在 THIRD开始的单元中 。 存放时,最低字节在地址最低处,则程序为:
MOV AX,FIRST
ADD AX,SECOND;进行字运算
MOV THIRD,AX
MOV AX,FIRST+2
ADC AX,SECOND+2
MOV THIRD+2,AX
⑶ 增量 ( 加 1) 指令 INC
格式,INC OPRD ; ( OPRD ) ← ( OPRD ) +1
功能,完成对指定的操作数 OPRD加 1,然后返回此操作数 。 此指令主要用于在 循环程序中修改地址指针和循环次数 等 。
规定:
① 操作数可为通用寄存器 reg,各种寻址方式的存储单元 mem。
② INC指令执行的结果影响 除进位标志 CF以外 的 5个标志位 AF、
OF,PF,SF和 ZF。
如,INC AL ; ( AL ) ← ( AL) +1
INC [BX] ; ( ( BX )) ← (( BX )) +1
2.减法指令 (Subtraction)
⑴ 减法指令 SUB
格式,SUB OPRD1,OPRD2; ( OPRD1) ← ( OPRD1 ) -( OPRD2 )
功能,完成两个操作数相减,即从 OPRD1中减去 OPRD2,结果放在 OPRD1中 。
例如,SUB CX,BX; ( CX ) ← ( CX ) -( BX )
SUB [BP],CL; (( BP)) ← (( BP)) -( CL )
规定,同 ADD。
⑵ 带借位位减法指令 SBB
格式,SBB OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) - ( OPRD2) - CF
SBB指令与 SUB类似,区别在于要减去借位标志 CF的值 。
SBB指令对标志位 AF,CF,OF,PF,SF和 ZF都有影响 。 同
ADC指令一样,SBB指令主要用于多字节运算中 。
⑶ 减量 ( 减 1) 指令 DEC
格式,DEC OPRD ; ( OPRD ) ← ( OPRD ) - 1
功能,完成对指定的操作数 OPRD减 1,然后返回此操作数 。 此指令主要用于在循环程序中修改地址指针和循环次数等 。
在相减时,把操作数作为一个无符号二进制数来对待 。 指令执行的结果,DEC指令执行的结果影响 除进位标志 CF以外 的 5个标志位 AF,OF,PF,SF和 ZF。
规定,同 INC。
例如,DEC [SI] ; (( SI ) )←( ( SI ) )- 1
DEC CL; ( C L ) ← ( C L ) - 1
⑷ 求补指令 NEG
格式,NEG OPRD
功能,取补 (NEGDate)----对操作数取补,即用零减去操作数,再把结果送回操作数 。
操作数 为通用寄存器 reg,存储单元 mem
例如,NEG AL ; ( AL) ← 0 -( AL )
( AL= 0011 1100) 则取补后为 1100 0100,即 0000 0000- 0011 1100= 1100 0100
若在字节操作时对 -128( 或在字操作时对 -32768取补 ),则操作数没变化,但标志 OF置位 。
此指令影响标志 AF,CF,OF,PF,SF和 ZF。 此指令的结果一般总是使标志 CF=1。 除非在操作数为零时,才使 CF=0。
⑸ 比较指令 CMP
格式,CMP OPRD1,OPRD2 ; ( OPRD1 ) -( OPRD2 )
功能,比较指令完成两个操作数相减,使结果反映在标志位上,
但并不把结果送回目的操作数 (即比较指令是不带回送的减法 )。
比较指令主要用于比较两个数之间的关系 。 在比较指令之后,根据 ZF标志即可判断两者是否相等 。
相等的比较:
① 若两者相等,相减以后结果为零,ZF标志为 1,否则为 0。
② 若两者不相等,则可在比较指令之后利用其它标志位的状态来确定两者的大小 。
大小的比较:
如果是两个无符号数 ( 如 CMP AX,BX) 进行比较,则可以根据 CF标志的状态判断两数大小 。 若结果没有产生借位 (CF=0),
显然 AX≥BX;若产生了借位 ( 即 CF= 1),则 AX< BX。
注,一般情况下,CMP指令后面经常会有一条条件转移指令,用来检查标志位的状态是否满足某种关系 。
例如,CMP AL,100;
将 ( AL ) 与 100比较,AL的内容不变,结果影响标志位 。
CMP DX,DI ;
将 ( DX ) 与 ( DI ) 比较,DX,DI的内容均不变,结果影响标志位 。
CMP CX,COUNT[BP] ;
将 ( CX ) 与 (( BP ) + COUNT) 比较,CX,BP、
(( BP) + COUNT) 的内容均不变,结果影响标志位 。
CMP COUNT[SI],AX ;
将 (( SI ) + COUNT ) 与 ( AX ) 比较,AX,SI,
(( SI ) + COUNT)) 的内容均不变,结果影响标志位 。
CMP指令执行后的标志位状态:( CMP A,B)
( 1) A,B均为无符号数时,ZF=0,则 A=B; CF=1,则 A<B ;
CF=0,则 A>B 。
( 2) A,B均为符号数,其均为正数,ZF=1,则 A=B; SF=1,
则 A<B ; SF=0,则 A>B 。
( 3) A,B均为符号数,其均为负数,ZF=1,则 A=B; SF=1,
则 A<B ; SF=0,则 A>B 。
( 4) A,B一个为正数,一个为负数时:
OF=0,若 SF=0,则 A>B 。
若 SF=1,则 A<B 。
OF=1,若 SF=0,则 A<B 。
若 SF=1,则 A>B 。
0111,1111(127)
0011,010(50)
+
1011,0001(-79)
127-(-50)=177
因为溢出了所以,OF=1,SF=1
同样,如果 A=-50,B=127,则结果是 OF=1,SF= 0。
综上所述:
( 1) A=B 用 ZF=1 判断 。
( 2) 两个无符号数的大小用 CF判断。
CF=1,A<B; CF=0,A>B。
( 3) 两个符号数的大小用 SF⊕ OF判断。
SF⊕ OF=1,A<B; SF⊕ OF=0,A>B。
在 8086系统中,有两条转移指令可实现 SF⊕ OF的判断。
JG/JNLE(大于,SF⊕ OF=0且 ZF=0 )
JL/JNGE (小于,SF⊕ OF=1且 ZF=0 )
3,乘法指令乘法指令分为无符号乘法指令和带符号乘法指令两类,
( 1)无符号乘法指令 MUL( 8位 /16位)
格式,MUL OPRD ;
8位,( AX) ← ( AL) ╳ ( OPRD )
16位,( DX) ( AX) ← ( AX) ╳ ( OPRD )
功能,完成字节与字节相乘,字与字相乘,且默认的操作数放在
AL或 AX中,而源操作数由指令给出 。 8位数相乘,结果为 16位数,
放在 AX中; 16位数相乘结果为 32位数,高 16位放在 DX,低 16位放在 AX中 。
规定:
① 源操作数只能是通用寄存器 reg和存储单元 mem,不能为立即数 。
② 影响 6个标志位 CF,DF,PF,SF,ZF和 AF。
例如,MOV AL,FIRST;
MUL SECOND ;结果为 AX=FIRST× SECOND
( 2) 带符号数乘法指令 IMUL( 8位 /16位 )
格式,IMUL OPRD ;
8位,( AX) ← ( AL) ╳ ( OPRD )
16位,( DX) ( AX) ← ( AX) ╳ ( OPRD )
功能,这是一条带符号数的乘法指令,同 MUL一样可以进行字节与字节、字和字的乘法运算。结果放在 AX或 DX,AX中。当结果的高半部分不是结果的低半部分的符号扩展时,标志位 CF
和 OF将置位。
规定,同 MUL 。
4,除法指令除法指令可分为以下四类:
(1) 无符号数除法指令 DIV ( 8位 /16位 )
格式,DIV OPRD;
8位,( AL) ← ( AX) /( OPRD ) …… ( AH) ( 余数 )
16位,( AX) ← ( DX) ( AX) /( OPRD ) …… ( DX ) ( 余数 )
功能,完成字节与字节除法,字与字除法,且默认目的操作数放在
AX或 DX,AX中,源操作数由指令给出,结果放在 AL,AX中 。
规定,① 基本同 MUL。 但在除法指令中,除数在源操作数中 。 在字节运算时被除数在 AX中;商在 AL中,余数在 AH中 。 字运算时被除数为 DX,AX构成的 32位数,商在 AX中,余数在 DX中 。
② 除法运算中,源操作数可为除立即寻址方式之外的任何一种寻址方式,且指令执行后所有的标志位都不确定,即或是 0,或是 1,但都无意义 。
例如,AX=2000H,DX=200H,BX=1000H,则 DIV BX执行后,
AX=2002H,DX=0000。
( 2) 带符号数除法 IDIV ( 8位 /16位 )
格式,IDIV OPRD;
8位,( AL) ← ( AX) /( OPRD ) …… ( AH) ( 余数 )
16位,( AX) ← ( DX) ( AX) /( OPRD ) …… ( DX ) ( 余数 )
功能,该指令执行过程同 DIV指令,但 IDIV指令认为操作数的最高位为符号位,除法运算的结果商的最高位也为符号位 。
规定,基本同 DIV。
由于除法指令中的字节运算要求被除数为 16位数,而字运算要求被除数是 32位数,当被除数不够位数时,需要对高 8位的 AH
( 或高 16位的 DX) 进行扩展 。
对于无符号数,AH,DX的扩展是将它们请 0。 对于有符号数,
在 8086/8088系统中往往需要用符号扩展的方法取得被除数所要的格式,因此指令系统中包括两条符号扩展指令 。
(3) 字节转换为字扩展指令 CBW
格式,CBW
功能,该指令执行时将 AL寄存器的最高位扩展到 AH,即若 AL
的 D7=0,则 AH=0;若 AL的 D7=1,则 AH=0FFH。
CBW指令不影响标志位 。
(4) 字转换为双字扩展指令 CWD
格式,CWD
功能,该指令执行时将 AX寄存器的最高位扩展到 DX,即若 AX
的 D15=0,则 DX=0;若 AX的 D15=1,则 DX=0FFFFH。
CWD指令不影响标志位 。
5,十进制调整指令计算机中的算术运算,都是针对二进制数的运算,而人们在日常生活中习惯使用十进制 。 为此在 8086/8088系统中,针对十进制算术运算有一类十进制调整指令 。
在计算机中人们用 BCD码表示十进制数,对于 BCD码,计算机中有两种表示方法:
压缩 BCD码,即规定每个字节表示两位 BCD数;
非压缩 BCD码,即用一个字节表示一位 BCD数,在这字节的高四位用 0填充 。
例如,十进制数 25D,压缩 BCD数为 25H;非压缩 BCD数为
0205H,用两字节表示 。 数字的 ASCII码是一种非压缩 BCD码
( 高 4位为 0011H),0----9的 ASCII码是 30H----39H。
每条十进制调整指令在使用时都与相应的算术运算指令配合,
并自动对相应的算术运算指令结果进行相应的十进制调整 。
相关的 BCD转换指令见下表。
十进制调整指令指令格式 指令说明
DAA 压缩的 BCD码加法调整
DAS 压缩的 BCD码减法调整
AAA 非压缩的 BCD码加法调整 ( ASCII码调整 )
AAS 非压缩的 BCD码减法调整 ( ASCII码调整 )
AAM 乘法后的 BCD码调整
AAD 除法 前 的 BCD码调整
(1)AAA加法的 ASCII调整指令调整原则:
a.若 AL的低 4位 >9或 AF= 1,则
AL=AL-6;
用与操作将 AL高 4位清零;
AF置 1,CF置 1,AH= AH+1;
b.否则,将 AL寄存器高 4位清 0。
例题:若 AL= BCD9,BL= BCD5,求两数之和。设 AH= 0,则
ADD AL,BL
AAA
0000 1001 … 9
0000 0101 … 5+
0000 1110 … 低 4位 >9+
0000 0110 … 加 6调整
0001 0100
0000 1111 … 清高 4位∧
0000 0100 … AL= 4
CF=1,AF=1,AH =1
结果为 AX= 0104H,表示非压缩十进制数 14
(2)DAA加法的十进制调整指令功能:将 2个压缩的 BCD数相加后的结果调整为正确的压缩 BCD数。
相加后的结果必须在 AL中,才能使用 DAA指令。
调整过程为:
若做加法后 AL中的低半字节 >9或 AF= 1,则
AL= AL+ 6,对低半字节进行调整;
若做加法后 AL中的高半字节 >9或 CF= 1,则
AL= AL+ 60H,对高半字节进行调整,并 CF置 1,否则 CF置 0
例题:若 AL= BCD88,BL= BCD49,求两数之和。运算过程为:
ADD AL,BL
DAA
1000 1000 … 88
0100 1001 … 49+
1101 0001 … AF=1+
0000 0110 … 加 6调整
1101 0111 … 调整后高半字节 >9
0110 0000 … 加 60H调整
0011 0111
结果为 AL= BCD37,CF=1
+
(3)AAS减法的 ASCII调整指令功能:在用 SUB或 SBB指令对两个非压缩十进数或以 ASCII码表示的十进制数进行相减后,对 AL中所得的结果进行调整,在 AL
中得到一个正确的非压缩十进制数之差。如有借位,则 CF= 1。
AAS指令必须紧跟在 SUB和 SBB指令之后。
调整过程为:若 AL寄存器的低 4位 >9或 AF= 1
AL= AL- 6;
将 AL寄存器高 4位清零
AH= AH-1;否则不需要调整。
例题:设 AL= BCD3,CL= BCD8,求两数之差。
SUB AL,CL
AAS
0000 0011 … BCD3
0000 1000 … BCD8-
1111 1011 … 低 4位 >9-
0000 0110 … 减 6调整
1111 0101
0000 1111 … 清高 4位∧
0000 0101 … AL= 5
结果为 5,CF= 1有借位
(4)DAS减法的十进制调整指令功能:在用 SUB或 SBB指令对两个压缩十进数进行相减后,对
AL中所得的结果进行调整,在 AL中得到一个正确的压缩十进制数。同样需要对 AL中的高半字节和低半字节进行调整。
例题:设 AL= BCD56,CL= BCD98,求两数之差。
SUB AL,CL
DAS
调整过程为:
若 AL中的低 4位 >9或 AF= 1,则
AL= AL- 6,AF置 1;
若 AL中的高半字节 >9或 CF= 1,则
AL= AL- 60H,CF置 1。
0101 0110 … BCD56
1001 1000 … BCD98-
1011 1110 … 低 4位 >9,CF= AF= 1-
0000 0110 … 减 6调整
1011 1000 … 高 4位 >9
0110 0000 … 减 60H调整∧
0101 1000 … BCD58
结果为 AL= BCD58,CF= 1 表示有借位
(5)AAM乘法的 ASCII调整指令调整过程为:把 AL的内容除以 10,商放在 AH中,余数放在 AL中。
例题:求两个非压缩十进制数 09和 06之乘积,可以实现为:
MOV AL,09H
MOV BL,06H
MUL BL ; AL =36H
AAM ;调整得 AH= 05H,AL= 04H
功能:对存在在 AL中的两个非压缩十进制数相乘的乘积进行十进制的调整,使得在 AX中得到正确的非压缩十进制数的乘积,
高位放在 AH中,低位放在 AL中。两个 ASCII码数相乘之前,必须先屏蔽掉每个数字的高半字节,从而使每个字节包含一个非压缩十进制数 (BCD数 ),再用 MUL指令相乘,乘积放到 AL中,
然后再用 AAM进行调整。
(6)AAD除法的 ASCII调整指令功能:做除法之前,把 BCD码转换成二进制数调整方式:
AL= AH× 10+ AL
AH= 00
6,算术运算指令对标志位的影响总结
( 1)加、减、乘、除指令均影响 6个标志位 CF,OF,PF,SF、
ZF和 AF。
( 2)加 1、减 1指令影响 除进位标志 CF以外 的 5个标志位 AF,OF、
PF,SF和 ZF。
( 3)取补指令( NEG)的 CF=1,影响其余的 5个标志位 AF,OF、
PF,SF和 ZF。
( 4)比较指令( CMP)影响 6个标志位 CF,OF,PF,SF,ZF和
AF。
( 5)压缩的 BCD码加、减法调整指令影响 除进位标志 OF以外 的 5
个标志位 AF,CF,PF,SF和 ZF。
( 6)非压缩的 BCD码加、减法调整指令影响 2个标志位 CF和 AF;
其余标志没有意义。
( 7)非压缩的 BCD码乘、除法调整指令影响 3个标志位 PF,SF和
ZF; CF,AF,OF没有意义。
3.3.3 逻辑运算和移位指令逻辑运算和移位指令包括逻辑运算、移位和循环移位指令三类指令。
1.逻辑运算指令功能,执行逻辑运算。与、或、非、异或等逻辑运算。
(1) 逻辑与指令 AND
格式,AND OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) ∧ ( OPRD2 )
功能,对两个操作数进行按位的逻辑“与”运算,结果送回目的操作数。
规定:
①目的操作数 OPRD1可以是累加器 AX( AL)、任一通用寄存器 reg,或内存单元 mem(所有寻址方式)。源操作数 OPRD2可以是立即数 data、寄存器 reg,也可以是内存单元 mem (所有寻址方式) 。
② 8086/8088的 AND指令可以进行字节操作,也可以进行字操作。
③利用与指令可实现屏蔽某个数据的某些位(使一个字或字节中的某些位清 0,而其余位不变),提取某些位或拆字。
例如,AND AL,0FH ;可完成拆字的动作,屏蔽高 4位。
(2) 逻辑或指令 OR
格式,OR OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) ∨ ( OPRD2 )
功能,对指定的两个操作数进行逻辑“或”运算。结果送回目的操作数。
规定,基本同 AND。利用或指令可实现置位某个数据的某些位
(使一个字或字节中的某些位置 1,而其余位不变)拼字。
例如,AND AL,0FH
AND AH,0F0H
OR AL,AH ; 完成拼字的动作
OR AX,0FFFH;将 AX低 12位置 1
OR BX,BX ; 清相应标志
(3) 逻辑非指令 NOT
格式,NOT OPRD; ( OPRD ) ← ( OPRD )
功能,对操作数求反,然后送回原处,操作数可以是寄存器 reg
或存储单元内容 mem。 此指令对标志无影响 。
规定,非指令常用于使某个数取反,或取反后 +1而得补码 。
例如,NOTAL
(4)逻辑异或指令 XOR
格式,XOR OPRD1,OPRD2;
( OPRD1 ) ← ( OPRD1) ∨ ( OPRD2 )
功能,对两个指定的操作数进行,异或,运算,结果送回目的操作数 。
规定:
① 目的操作数 OPRD1可以是累加器 AX( AL),可以是任一个通用寄存器 reg,也可以是一个存储单元 mem(全部寻址方式 )。
源操作数可以是立即数 data,寄存器 reg,也可以是存储单元
mem(所有寻址方式 )。
② 利用异或指令可实现某个寄存器清 0,或使目的操作数的某些位取反 ( 使一个字或字节中的某些位取反,而其余位不变 ) 。
例如,XOR AL,AL ;使 AL清 0
XOR SI,SI ;使 SI清 0
XOR CL,0FH ;使低 4位取反,高 4位不变
(5)测试指令 TEST
格式,TEST OPRD1,OPRD2 ; ( OPRD1) ∧ ( OPRD2 )
功能,完成与 AND指令相同的操作 ( 与操作 ),结果反映在标志位上,但并不送回 ( 结果不保存 ) 。
功能,通常使用它进行测试 。 测试目的操作数的某些位是 1还是 0,
用 ZF标志判断 。
① 判断目的操作数的某些位是否为 1的方法:
TEST AL,01H; ( AL ) ∧ ( 01H )
若 AL0=0,则 ZF=1;若 AL0=1,则 ZF=0。
② 判断目的操作数的某些位是否为 0的方法:
TEST AL,0FH; ( AL ) ∧ ( 0FH )
若 AL0~3=0000B,则 ZF=1;若 AL0≠0000B,则 ZF=0。
例如,若要检测 AL中的最低位是否为 1,为 1则转移 。 可用以下指令:
TEST AL,01H
JNZ THERE
……
THERE:
注,① 逻辑运算类指令中,源操作数为 reg,mem,data;目的操作数为 reg,mem( NOT指令只有一个操作数 ) 。 单操作数指令 NOT的操作数不能为立即数 。 双操作数逻辑指令中,必须有一个操作数为寄存器寻址方式,且目的操作数不能为立即数 。
② 逻辑运算类指令对标志位的影响情况如下,NOT不影响标志位,其它四种指令将使 CF=OF=0,AF无定义,而 SF,ZF和 PF
则根据运算结果而定 。
③ 利用 与指令 可实现屏蔽某个数据的某些位 ( 使一个字或字节中的某些位清 0,而其余位不变 ),提取某些位或拆字 。 利用 或指令可实现置位某个数据的某些位 ( 使一个字或字节中的某些位置 1,
而其余位不变 ) 拼字 。 非指令 常用于使某个数取反,或取反后 +1而得补码 。 利用 异或指令 可实现某个寄存器清 0,或使目的操作数的某些位取反 ( 使一个字或字节中的某些位取反,而其余位不变 ) 。
通常使用 测试指令 进行测试 。 测试目的操作数的某些位是 1还是 0,
用 ZF标志判断 。
2,移位指令格式,操作码 OPRD,CNT
功能,将 OPRD的内容移位 CNT次 。
规定,① OPRD可以是累加器 AX( AL),可以是任一个通用寄存器 reg,也可以是一个存储单元 mem;其寻址方式可以采用除立即寻址外的任何寻址方式 。
② CNT=1时,只移 1位; CNT>1时,可将指令格式中的 CNT
改为 CL寄存器,并在移位指令前将移位次数预先送入 CL寄存器中 。
③ 影响 CF,SF,ZF,PF标志,在移 1位时,还影响 OF标志 。
④ 算术移位助记符为 SA,逻辑移位为 SH,循环移位为 RO,
带进位位的循环移位为 RC。 R为右移,L为左移 。
⑤ 算术移位适用于带符号数的? 2,/2。 逻辑移位适用于无符号数的 × 2,÷ 2。
( 1) 算术 /逻辑移位指令
① 算术左移或逻辑左移指令,SAL/ SHL OPRD,M ;
② 算术右移指令,SAR OPRD,M
③ 逻辑右移指令,SHR OPRD,M
规定,① M是移位次数,可以是 1或寄存器 CL
② 算术 /逻辑移位指令可以对寄存器或存储器单元进行指定的移位,可以进行字节或字操作;可以一次只移 1位,也可以移位由寄存器 CL中的内容规定的次数 。
算术 /逻辑移位 指令操作示意图如下:
( 2) 循环移位指令循环左移,ROL OPRD,M ;
循环右移,ROR OPRD,M ;
带进位循环左移,RCL OPRD,M ;
带进位循环右移,RCR OPRD,M ;
前两条循环指令,未把标志位 CF包含在循环的环中,后两条把标志位 CF包含在循环的环中,作为整个循环的一部分 。 循环移位指令操作示意图如下:
功能,循环指令可以对字节或字进行操作 。 操作数可以是寄存器
reg,也可以存储器单元 mem。 可以是循环移位一次,也可以循环移位由 CL的内容所决定的次数 。
左移一位,只要左移以后的数未超出一个字节或一个字的表达范围,则原数的每一位的权增加了一倍,相当于原数乘 2。 右移一位相当于除以 2。
例如,乘 10的操作在数的输入输出过程中乘 10的操作是经常要进行的 。 而
X× 10=X× 2+X× 8,也可以采用移位和相加的办法来实现 × 10。
为保证结果完整,先将 AL中的字节扩展为字 。
MOV AH,0
SAL AX,1 ; X × 2
MOV BX,AX ;移至 BX中暂存
SAL AX,1 ; X × 4
SAL AX,1 ; X × 8
ADD AX,BX ; X × 10
3.3.4 串操作类指令 ( 简单介绍 )
串操作类指令就是用一条指令实现对一串字符或数据 ( 数据串 ) 的操作 。 这些数据串可以是字节串,也可以是字串 。
特点:
① 串操作类指令是唯一的一组 源和目的操作数均在存储单元的指令 。 源串在数据段,目的串在附加段 。 各指令所使用的默认寄存器是:
源串地址 DS,SI
目的串地址 ES,DI
字串长度 CX
存取或搜索的默认值 AL
② 串操作时,地址的修改往往与方向标志 ( DF) 有关 。
DF=1,SI,DI作自动减量 ( 自动 -1) 修改;
DF=0,SI,DI作自动增量 ( 自动 +1) 修改 。
③ 建立方向标志 ( FR) 的方法:
可用传送指令硬置 FR,也可以用建立方向标志的指令:
CLD ; DF=0
STD ; DF=1
④ 任何一个串操作指令均可在指令前面加上一个重复操作作为前缀,于是之仍旧重复执行,直至 CX,ZF满足要求为止 。
1,重复指令前缀串操作类指令可以与重复指令前缀配合使用 。 从而使操作得以重复进行,及时停止 。 重复指令前缀的几种形式见下表所示 。
汇编格式重复前缀 执行过程影响指令
REP
① 若 (CX)= 0,则退出; ② CX=CX-1;
③执行后续指令; ④重复① ----③
MOVS,
STOS
LODS
REPE/
REPZ
① 若 (CX)= 0或 ZF=0,则退出; ② CX=CX-1; ③ 执行后续指令; ④重复① ----③
CMPS
SCAS
REPNE/
REPNZ
① 若 (CX)= 0或 ZF=1,则退出; ② CX=CX-1; ③执行后续指令; ④重复① ----③
CMPS
SCAS
2,串指令 ( 阅读教材 P97----100)
串指令共有五种,具体见下表。
串操作指令功能 指令格式 执行操作串传送 MOVS DST,SRC
MOVSB
MOVSW
由操作数说明是字节或字操作;其余同 MOVSB或 MOVSW
[(ES,DI)]←[(DS,SI)]; SI=SI± 1,DI=DI± 1; REP控制重复前两步
[(ES,DI)]←[(DS,SI)]; SI=SI± 2,DI=DI± 2; REP控制重复前两步串比较 CMPS DST,SRC
CMPSB
CMPSW
由操作数说明是字节或字操作;其余同 CMPSB或 CMPSW
[(ES,DI)]- [(DS,SI)]; SI=SI± 1,DI=DI± 1;重复前缀控制前两步
[(ES,DI)]- [(DS,SI)]; SI=SI± 2,DI=DI± 2;重复前缀控制前两步串搜索 SCAS DST
SCASB
SCASW
由操作数说明是字节或字操作;其余同 SCASB或 SCASW
AL- [(ES,DI)]]; DI=DI± 1;重复前缀控制前两步
AX- [(ES,DI)]; DI=DI± 2;重复前缀控制前两步存串 STOS DST
STOSB
STOSW
由 操作数说明是字节或字操作;其余同 STOSB或 STOSW
AL→[(ES,DI)]]; DI=DI± 1;重复前缀控制前两步
AX→[(ES,DI)]; DI=DI± 2;重复前缀控制前两步取串 LODS SRC
LODSB
LODSW
由操作数说明是字节或字操作;其余同 LODSB或 LODSW
[(DS,SI)]]→ AL; SI=SI± 1;重复前缀控制前两步
[(DS,SI)]→ AX; SI=SI± 2;重复前缀控制前两步
MOVS指令的功能把数据段中由 SI间接寻址的一个字节 (或一个字 )传送到附加段中由 DI间接寻址的一个字节单元 (或一个字单元 )中去,然后,根据方向标志 DF及所传送数据的类型 (字节或字 )对 SI及 DI进行修改,在指令重复前缀 REP的控制下,可将数据段中的整串数据传送到附加段中去 。
[例 ] 在数据段中有一字符串,其长度为 17,要求把它们传送到附加段中的一个缓冲区中,其中源串存放在数据段中从符号地址 MESS1开始的存储区域内,
每个字符占一个字节; MESS2为附加段中用以存放字符串区域的首地址 。
实现上述功能的程序段如下:
LEA SI,MESS1 ;置源串偏移地址
LEA DI,MESS2 ;置目的串偏移地址
MOV CX,17 ;置串长度
CLD ;方向标志复位
REP MOVSB ;字符串传送其中,最后一条指令也可写成
REP MOVS ES,BYTE PTR[DI],DS,[SI]
或 REP MOVS MESS2,MESS1
CMPS指令的功能把数据段中由 SI间接寻址的一个字节 (或一个字 )与附加段中由 DI间接寻址的一个字节 (或一个字 )进行比较操作,使比较的结果影响标志位,然后根据方向标志 DF及所进行比较的操作数类型 (字节或字 )对 SI及 DI进行修改,在指令重复前缀 REPE/REPZ或者 REPNE/REPNZ的控制下,可在两个数据串中寻找第一个不相等的字节 (或字 ),或者第一个相等的字节 (或字 )。
[例 ] 在数据段中有一字符串,其长度为 17,存放在数据段中从符号地址
MESS1开始的区域中;同样在附加段中有一长度相等的字符串,存放在附加段中从符号地址 MESS2开始的区域中,现要求找出它们之间不相匹配的位置 。
实现上述功能的程序段如下;
LEA SI,MESS1 ;装入源串偏移地址
LEA DI,MESS2 ;装入目的串偏移地址
MOV CX,17 ;装入字符串长度
CLD ;方向标志复位
REPE CMPSB
上述程序段执行之后,SI或 DI的内容即为两字符串中第一个不匹配字符的下一个字符的位置 。 若两字符串中没有不匹配的字符,则当比较完毕后,
CX= 0,退出重复操作状态 。
SCAS指令的功能用由指令指定的关键字节或关键字 (分别存放在 AL及 AX 寄存器中 ),与附加段中由 DI间接寻址的字节串 (或字串 )中的一个字节 (或字 )进行比较操作,使比较的结果影响标志位,然后根据方向标志 DF及所进行操作的数据类型 (字节或字 ) 对 DI进行修改,在指令重复前缀 REPE/REPZ或 REPNE/REPNZ的控制下,可在指定的数据串中搜索第一个与关键字节 (或字 )匹配的字节 (或字 ),或者搜索第一个与关键字节 (或字 )不匹配的字节 (或字 )。
[例 ] 在附加段中有一个字符串,存放在以符号地址 MESS2开始的区域中,长度为 17,要求在该字符串中搜索空格符 (ASCII码为 20H)。
实现上述功能的程序段如下:
LEA DI,MESS2 ;装入目的串偏移地址
MOV AL,20H ;装入关键字节
MOV CX,17 ;装入字符串长度
REPNE SCASB
上述程序段执行之后,DI的内容即为相匹配字符的下一个字符的地址,
CX中是剩下还未比较的字符个数 。 若字符串中没有所要搜索的关键字节 (或字 ),
则当查完之后 (CX)= 0退出重复操作状态 。
STOS指令的功能把指令中指定的一个字节或一个字 (分别存放在 AL及 AX寄存器中 ),传送到附加段中由 DI间接寻址的字节内存单元 (或字内存单元 )中去,然后,根据方向标志 DF及所进行操作的数据类型
(字节或字 )对 DI进行修改操作 。 在指令重复前缀的控制下,可连续将 AL( AX) 的内容存入到附加段中的一段内存区域中去,该指令不影标志位 。 例 要对附加段中从 MESS2开始的 5个连续的内存字节单元进行清 0操作,可用下列程序段实现:
LEA DI,MESS2 ;装入目的区域偏移地址
MOV AL,00H ;为清零操作准备
MOV CX,5 ;设置区域长度
REP STOSB
LODS指令的功能从串中取指令实现从指定的字节串 (或字串 )中读出信息的操作 。
[例 ] 比较 DEST和 SOURCE中的 500个字节,找出第一个不相同的字节,如果找到,则将 SOURCE中的这个数送 AL中 。
CLD
LEA DI,ES,DEST
LEA SI,SOURCE
MOV CX,500
REPE CMPSB
JCXZ NEXT ;CX=0则转移
MATCH,DEC SI
MOV AL,BYTE PTR[SI]
NEXT,……
3.3.5 控制转移类指令( P100)
转移类指令可改变 CS与 IP的值或仅改变 IP的值,以改变指令执行的顺序。
控制转移指令,凡是能改变指令执行顺序的指令统称为控制转移指令。
控制转移指令分类,共分六类,无条件转移指令、子程序调用和返回指令、条件转移指令、循环控制指令、中断指令、处理器控制命令。
1.程序转移的地址( P100)
程序的寻址是由 CS和 IP完成的,为使程序转移到一个新的地址执行,同时改变 CS和 IP或只改变 IP的内容均可。
可直接转移(转移的目的地址直接出现在指令的机器码中)。
也可间接转移(转移的目的地址间接存储于某一个寄存器或某一个内存变量中)。
( 1)段间转移、段间调用同时改变 CS和 IP内容。将下一条指令的 IP入栈( SP-2),CS
入栈( SP-2),返回时出栈。
( 2)段内转移、段内调用只改变 IP的内容,将下一条指令的 IP入栈( SP-2),返回时出栈 。可分为 16位偏移量 NEAR和 8位偏移量 SHORT,16位偏移量适用于无条件转移指令和条件转移指令; 8位偏移量适用于条件转移指令,范围为 -128 ---- +127。
注,段间转移、段间调用、段内转移、段内调用的 CS和 IP的入栈和出栈 是由机器自动完成的。
2.无条件转移指令( P101)
无条件转移指令可以转移到存储器的任何程序段。
格式,JMP [转移方式 ]OPRD
功能,转移到 OPRD所指向的存储器单元处执行程序。
规定,OPRD可为除立即数外的各种寻址方式。
( 1)段内直接短转移指令格式,JMP SHORT OPRD;( IP) ← ( IP) + OPRD
规定,OPRD为 8位地址偏移量,为符号地址(标号)。由
SHORT指出,范围为 -128 ---- +127。
( 2)段内直接近转移指令格式,JMP NEAR PTR OPRD;( IP) ← ( IP) + OPRD
规定,OPRD为 16位地址偏移量,为符号地址(标号) 。由
NEAR指出,NEAR可省略( 指令可写成 JMP OPRD )。目的地址与 JMP指令应处于同一地址段范围之内。
( 3)段内间接转移指令格式,JMP WORD PTR OPRD;( IP) ← [EA]
规定,OPRD可为除立即数外的各种寻址方式。若 OPRD为 16位寄存器,则( IP) ← ( reg);若 OPRD为存储器中的一个字,则
( IP) ← ( add+1) ( add)。如:
JMP WORD PTR[BX]; ( IP ) ← (( DS)? 16 +( BX))
JMP WORD PTR BX ; ( IP ) ← ( BX)
( 4)段间直接(远)转移指令格式,JMP FAR PTR OPRD;( IP) ← OPRD的段内偏移地址
( CS) ← OPRD所在的段地址规定,OPRD为直接寻址方式。
( 5)段间间接转移指令格式,JMP DOWRD PTR OPRD; ( IP) ← [EA]
( CS) ← [EA+2]
3.子程序调用和返回指令 ( P105)
( 1)子程序调用指令 CALL
CALL指令用来调用一个过程或子程序 。 由于过程或子程序有段间 (即远程
FAR)和段内调用 ( 即近程 NEAR) 之分 。 所以 CALL也有 FAR和 NEAR之分 。
因此返回指令 RET也分段间与段内返回两种 。
格式,CALL 子程序名 DST
段内调用,CALL NEAR PTR OPRD ;
( SP) ← ( SP-2),(( SP) +1) ( SP)) ← ( IP),
( IP ) ← 子程序 DST的地址 ( 即,IP+16位位移量 )
规定,CALL指令首先将当前 IP内容压入堆栈 。 当执行 RET指令而返回时,从堆栈中取出一个字放入 IP中 。
段间调用,CALL FAR PTR OPRD ;
( SP) ← ( SP-2),(( SP) +1),( SP)) =( CS ) ;
( SP) ← ( SP-2),(( SP) +1),( SP)) =( IP ) ;
( IP ) =[EA]; ( CS ) =[EA+2]
规定,CALL指令先把 CS压入堆栈,再把 IP压入堆栈。当执行
RET指令而返回时,从堆栈中取出一个字放入 IP中,然后从堆栈中再取出第二个字放入 CS中,作为段间返回地址。
( 2)子程序返回指令 RET
格式,RET ;( IP ) ← (( SP) +1,SP),
( SP ) ← ( SP) + 2
RET n ; ( IP ) ← (( SP+1),SP),
( SP ) ← ( SP+2 ),
返回后 ( SP ) ← ( SP+ n )
规定,RET n 指令要求 n 为 0----0FFFFH范围内的偶数,当
RET正常返回后,再做 SP=SP+n操作。 相当于子程序返回后,
将栈中的 n个单元腾出来了。主要用于主程序为某个子程序提供一定的参数或参数地址。
4.条件转移指令( P109)
8086的条件转移指令是根据标志寄存器中各标志位的状态,
决定程序是否进行转移 。 条件转移指令的目的地址必须在现行的代码段 (CS)内,并且以当前指令指针寄存器 IP内容为基准,
其位移必须在十 127~— 128的范围之内 。
格式,指令助记符 目的地址功能,当条件满足时,转到目的地址处继续执行 。
规定,对于无符号数,A----高于,B----低于,E----等于 。
对于带符号数,G ----大于,L----小于,E----等于 。
指令 JG( 大于 ) 与 JNLE( 不小于 ) 是等同的,同理,
JG/JNLE,JL/JNGE,JGE/JNL,JLE/JNG,JA/JNBE,
JB/JNAE,JAE/JNB,JBE/JNA均是等同的 。
( 1) 标志位转移指令 ( J__/JN__) ( P110表 3-11)
结果为零 /结果不为零转移,JZ( /JE) /JNZ( /JNE) OPRD
结果为负数 /结果为正数转移,JS/JNS OPRD
结果奇偶校验为偶 /结果奇偶校验为奇转移:
JP( /JPE ) /JNP( /JPO ) OPRD
结果溢出 /结果不溢出转移,JO/JNO OPRD
结果有进位 ( 借位 ) /结果无进位 ( 借位 ) 转移:
JC/JNC OPRD
( 2) 不带符号数比较转移指令 ( P110表 3-12,注意条件 )
高于或不低于等于转移,JA/JNBE OPRD (CF∨ ZF=0)
高于等于或不低于转移,JAE/JNB OPRD (CF=0)
低于或不 高 于等于转移,JB/JNAE OPRD (CF=1)
低于等于或不 高 于转移,JBE/JNA OPRD (CF∨ ZF=1)
( 2) 带符号数比较转移指令大于或不小于等于转移,JG/JNLE OPRD ((SF⊕ OF) ∨ ZF=0)
大于等于或不低于转移,JGE/JNL OPRD (SF⊕ OF=0)
小于或不大于等于转移,JL/JNGE OPRD (SF⊕ OF=1)
小于等于或不大于转移,JLE/JNG OPRD ((SF⊕ OF) ∨ ZF=1)
( 3) 测试转移指令
CX=0 时转移,JCXZ OPRD
注,条件转移指令是根据两个数的比较结果或某些标志位的状态来决定转移的。在条件转移指令中,有的根据对符号数进行比较和测试的结果实现转移。这些指令通常对溢出标志位 OF和符号标志位 SF进行测试。对无符号数而言,这类指令通常测试标志位
CF。对于带符号数分大于、等于、小于 3种情况;对于无符号数分高于、等于、低于 3种情况。在使用这些条件转移指令时,一定要注意被比较数的具体情况及比较后所能出现的预期结果。
5,循环控制指令( P112)
对于需要重复进行的操作,微机系统可用循环程序结构来进行,8086系统为了简化程序设计,设置了一组循环指令,这组指令主要对 CX或标志位 ZF进行测试,确定是否循环 。
( 1) LOOP OPRD;
( CX ) ← ( CX ) -1,若 CX≠ 0,则循环,否则顺序执行 。
( 2) LOOPNZ/LOOPNE OPRD;
( CX ) ← ( CX ) -1,若 CX≠ 0 且 ZF=0,则循环,否则顺序执行 。
( 3) LOOPZ/LOOPE OPRD;
( CX ) ← ( CX ) -1,若 CX≠ 0 且 ZF=1,则循环,否则顺序执行 。
( 4) JCXZ OPRD;
( CX ) ← ( CX ) -1,若 CX=0,则循环,否则顺序执行 。
6,中断指令( P115)
( 1) INT n ;
( SP) ← ( SP) -2,( ( SP) +1,( SP) ) ← ( FR),FR入栈
( SP) ← ( SP) -2,( ( SP) +1,( SP) ) ← ( CS),CS入栈
( SP) ← ( SP) -2,( ( SP) +1,( SP) ) ← ( IP),IP入栈
( IP) ← ( n? 4),( CS) ← ( n? 4+2)
n:中断类型号,范围为 0----255。有关中断类型号、中断向量在第 5章中断方式中介绍。
( 2) INTO
功能,INTO放在算术运算指令之后,若算术运的 OF=1,则执行溢出中断(内部中断,中断类型号为 4,同 INT 4),否则继续执行。
( 3) IRET
( IP) ← ( ( SP) +1,( SP) ),( SP) ← ( SP) +2,IP出栈
( CS) ← ( ( SP) +1,( SP) ),( SP) ← ( SP) +2,CS出栈
( FR) ← ( ( SP) +1,( SP) ),( SP) ← ( SP) +2,FR出栈功能,中断服务子程序返回指令,是中断服务子程序的最后一条指令,功能类似于子程序返回指令 RET。
7,处理器控制指令( P117)
处理器控制指令只完成简单的控制功能,无操作地址,又称为无地址指令。
( 1)标志操作指令功能,只对标志位(主要有 CF,DF和 IF三个标志)进行操作,只影响相应的一个标志。
规定,清标志位为 CL,置标志位为 ST,再加上标志的第一个字母。
相应的指令如下:
清进位标志,CLC ; ( CF ) ← 0
置进位标志,STC; ( CF ) ← 1
进位标志取反,CMC; ( CF ) ← ( CF )
清方向标志,CLD; ( DF ) ← 0
置方向标志,STD; ( DF ) ← 1
关中断标志,CLI; ( IF ) ← 0,不允许中断开中断标志,STI; ( IF ) ← 1,允许中断
( 2)处理器外部同步命令处理器外部同步命令用以控制处理器的工作状态,均不影响标志位 。具体指令如下:
暂停指令,HLT
处理器处于什么也不做的暂停状态,可由中断请求,复位等唤醒继续执行 。
等待指令,WAIT
使处理器处于等待状态,CPU每隔 4个时钟周期测试一次 TEST
引脚线 ( 23脚 ),直至 TEST引脚线为有效低电平时,CPU才脱离等待状态 。
交权指令,ESC
CPU将控制权交给其他协处理器,使协处理器从系统指令流中取得指令 。
总线封锁指令,LOCK
可放在任一条指令前作为前缀,它使 CPU在执行下一条指令期间发出总线封锁信号 ( LOCK ),将总线封锁,其它的主设备不能控制总线 。 即不能访问存储器和外设 。
空操作指令,NOP
常用于程序的延时和调试 。
到此为止,我们已把 8086的指令系统介绍完了 。
8,指令的执行时间和软件延时( P119)
每条指令执行时都需要几个时钟周期。 ( P119表 3-14,3-15)
8086的时钟周期:主频率的倒数。
例,延时 10mS的程序。设 CPU的主频为 5MHz。
分析,延时程序的目的是使 CPU执行一段程序,没有具体的执行结果,但需要这段程序的执行时间。如:等待有效信号的出现,
键盘的去抖动等。
延时程序一般通过循环程序实现。
需要了解:
时钟周期 =主频率的倒数 =1/( 5× 10-6) =0.2μs
指令的时钟周期数:
MOV CX,N 4
LOOP AA 循环时为 17,不循环时为 5
NOP 3
RET 段内 16,段间 24
延时 10ms需要的时钟周期数 = 10ms/ 0.2μs=50000
解:编写延时程序:
DELAY10,MOV CX,N 4
DLY1,NOP 3 × N
LOOP DLY1 17 × ( N-1) + 5
RET 16
应该有 50000=4+ 3 × N+ 17 × ( N-1) + 5+16,才能实现要求的延时。则:
N=2500=09C4H
实际的延时程序如下:
DELAY10,MOV CX,09C4H
DLY1,NOP
LOOP DLY1
RET
思考:
这个延时程序是否存在误差,如何消除误差?
作业:
P121
1,2,6,10,13,15