第三章 8086 指令系统

Preview:

DESCRIPTION

第三章 8086 指令系统. 指令系统是微处理器( CPU )所能执行的指令的集合,它与微处理器有密切的联系,不同的微处理器有不同的指令系统。在本章中我们主要讲解 INTEL 公司生产的 8086/8088CPU 的寻址方式以及各种指令系统,并通过具体实例讲述了各条指令的功能和使用方法。 通过本章的学习,读者应该掌握以下内容: • 4 种操作数的寻址方式 • 常用指令的格式、功能、以及对标志位的影响. §3.1 8086 的寻址方式. 汇编指令的格式如下 :. 操作码 操作数. 操作码: 指令操作类型;(必须有) - PowerPoint PPT Presentation

Citation preview

第三章 8086 指令系统

指令系统是微处理器( CPU )所能执行的指令的集合,它与微处理器有密切的联系,不同的微处理器有不同的指令系统。在本章中我们主要讲解 INTEL 公司生产的 8086/8088CPU 的寻址方式以及各种指令系统,并通过具体实例讲述了各条指令的功能和使用方法。通过本章的学习,读者应该掌握以下内容: •4 种操作数的寻址方式 • 常用指令的格式、功能、以及对标志位的影响

§3.1 8086 的寻址方式

操作码 操作数

操作码:指令操作类型;(必须有)

操作数:指令所需操作数或操作数的地址;操作数可以有一个,也可以有两个(一个源操作数,一个目的操作数),也可以没有。

例: MOV AX , CX ;将 CX 的内容送入 AX 中。

INC AX

STI

汇编指令的格式如下 :

一、 立即寻址方式

指令操作数部分直接给出指令的操作数,操作数与操作码一起存入代码段中。立即数有 8 位和 16 位。

例 : MOV AL,5 ;源操作数为立即寻址指令执行后, AL=05H , 8 位数据 05H 存入 AL 寄存器。

例 : MOV AX , 3064H ;源操作数为立即寻址指令执行后, AX=3064H , 16 位数据 3064H 存入 AX寄存器。

注意:①立即数只能作源操作数,不能作目的操作数。

② 以 A 、 B 、 C 、 D 、 E 、 F 开头的数字出现在指令中时,必须在前面加一个数字 0 。

③ 立即数可以送到寄存器、存储器中。

例:下列指令是错误的。

MOV 2000H , AX

MOV AL , B5H

而指令 MOV [2000H] , 1234H 是对的。

二、 寄存器寻址方式

寄存器寻址方式的操作数是寄存器的值,指令中直接使用寄存器名,包括 8 位或 16 位通用寄存器和段寄存器。可使用的 16 位寄存器: AX 、 BX 、 CX 、DX 、 SI 、 DI 、 SP 、 BP 、 CS 、 DS 、 ES 、 SS ;其中 AX 、 BX 、 CX 、 DX 可分成两个 8 位寄存器别使用。

例: MOV AX , CX ;( AX ) ( CX )

MOV AL , 1 ;( AL ) 1

注意:① CS 不能作为目的操作数,如 MOV CS , AX 是错误的指令。

② 源操作数必须与目的操作数相匹配。如

MOV AL , BX 是错误的

三、 存储器寻址方式

在存储器寻址方式中,操作数是某个内存单元的内容(值),指令中给出的是内存单元的有效地址 EA(即偏移地址),段地址通常在隐含的某个段寄存器中。由于内存单元的地址的给出方式不同,存储器寻址又可分为以下几种寻址方式:直接寻址、寄存器间址、寄存器相对寻址、基址变址寻址、基址变址相对寻址。

1 、直接寻址方式 形式: MOV AX , [nn] MOV AX , X

在直接寻址方式中,操作数的偏移地址 ( 有效地址EA) 直接用指令加以指定 ( 有直接地址值和标号两种形式 ) ,它存放在代码段中指定操作码之后,但操作数一般存放在存储器的数据段中,所以必须先求出操作数的物理地址,然后再访问存储器才能取得操作数。段地址隐含的由 DS 指定,也可以 ES 指定,但需在指令中指明。最后存储器地址为: DS: 偏移地址 或 ES: 偏移地址。

例: MOV AX , [2000H] 将 DS:2000H 单元内容送入 AX

MOV AL , [2000H] 将 DS : 2000H 单元的内容取一个字节送 AL

例: MOV AX , ES : [2000H] 将 ES : 2000H 单元中的内容送入 AX

MOV AL , X X 必须是数据段中用 DB 定义的变量

传送原则:低地址的内容(字节)送寄存器的低位,高地址的内容送寄存器的高位。

2 、寄存器间接寻址寄存器间接寻址方式的操作数形式为: [reg]操作数的有效地址包含在基址寄存器 BX ,基址指针 BP 或一个变址寄存器( SI 或 DI )中。寄存器间接寻址要用方括号括起来,以便与寄存器操作数相区别。

例: MOV AX , [BX] ;将由 BX 决定的存储单元的内容送到 AX 寄存器。

0000

0001

0002

0003

BB

AA

TAB :

AX

AH AL

AA BB

间接寻址

数据段

0001BX

操作数在存储器中,指令中寄存器内容作为操作数所在单元的有效地址。

( BX )

( SI )

( DI )

( BP )

有效地址 = 段寄存器为 DS

段寄存器为 SS

物理地址计算方法:

物理地址 = ( DS ) * 16 + ( BX )或( SI )或( DI )

物理地址 = ( SS ) * 16 + ( BP )

例:已知:( DS ) =2100H ,( DI ) =2000H

指令: MOV AX , [DI] ;( AX ) (( DI ))

物理地址 = ( DS ) * 16 + ( DI )

=2100H * 16 + 2000H

=21000H + 2000H

=23000H

指令结果:将 23000H 单元内容送 AL 中,

将 23001H 单元内容送 AH 中。

例: MOV AX , DS : [BP]

MOV BX , ES : [SI]

3 、寄存器相对寻址方式

操作数在存储器内,指令中寄存器内容与指令指定的位移量( DISP )之和作为操作数所在单元的有效地址。

( BX ) DISP8

( SI )

( DI )

( BP ) DISP16

有效地址 = 段寄存器为 DS

段寄存器为 SS

+

物理地址 = ( DS ) * 16 + ( BX ) +DISP8

( SI )、( DI )、 DISP16 类同。

物理地址 = ( SS ) *16 + ( BP ) +DISP16

例: 如果 (DS)=3000H, (SI)= 2000H, COUNT=3000H, 则执行指令 MOV AX , CONUT[SI] ,求出此种寻址方式对应的有效地址和物理地址。

有效地址 = 2000H + 3000H = 5000H

物理地址 = ( DS ) *16 + 5000H

=30000H + 5000H =35000H

4 、基址变址寻址方式:

操作数在存储器中,指令将基址寄存器( BX 或 BP )与变址寄存器( SI 或 DI )内容之和作为操作数所在存储单元的有效地址。

( BX ) ( SI )

( BP ) ( DI )有效地址 = +

物理地址 = ( DS ) * 16 + ( BX ) + ( SI )或( DI )

物理地址 = ( SS ) * 16 + ( BP ) + ( SI )或( DI )

例: MOV AX , [BX+DI] 或 MOV AX , [BX][DI] DS:(BX)+(DI) 字存储单元内容送 AX 。

例: MOV AX , [BP+SI] 或 MOV AX , [BP][SI] SS:(BP)+(SI) 字存储单元内容送 AX 。

例:如果 (DS)=2100H, (BX)= 0158H, (DI)=10A5H, EA=11FDH, 则执行指令 MOV AL , [BX][DI]

有效地址: EA= ( BX ) + ( DI ) =0158H+10A5H=11FDH

物理地址:( DS ) * 16 + 有效地址 =21000H+11FDH=221FDH

执行结果:将 221FDH 单元内容送入寄存器 AL 中。5 、基址变址相对寻址方式

操作数在存储器内,指令将基址寄存器( BX 或 BP )与变址寄存器( SI 或 DI )的内容之和再加上位移量( 8 位或 16 位),得到操作数所在单元的有效地址。

( BX ) ( SI ) DISP8

( BP ) ( DI ) DISP16有效地址 = + +

物理地址 = ( DS ) * 16 + ( BX )产生的有效地址

物理地址 = ( SS ) * 16 + ( BP )产生的有效地址

例:已知:( DS ) =3000H ,( BX ) =2000H ,( SI ) =1000H , MK=0250H

指令: MOV AX , MK[BX][SI]

或 MOV AX , MK[BX+SI]

或 MOV AX , [MK+BX+SI]

有效地址: MK+ ( BX ) + ( SI ) =0250H+2000H+0100H

=3250H

物理地址:( DS ) *16 + 有效地址 =30000H+3250H=33250H

执行结果:将 33250H 单元内容送 AL , 33251H 内容送 AH 。

6 、 段超越

当操作数在内存单元时,系统根据隐含约定,自动将寄存器 DS 或 SS 的值作为段地址。然而,当操作数段地址不在隐含的段寄存器时,可以使用段超越前缀取代其隐含约定。 段超越前缀形式为: 段寄存器名: MEM例如:

MOV AX , ES : [BP] ;段地址在 ESMOV AX , CS : [BX] [SI] ;段地址在 CS段地址的基本约定和允许超越的情况如表所示:

存储器存取方式 约定段 允许超越段 偏移地址

取指令堆栈操作源串目的串BP作基址通用数据读写

CS

SS

DS

ES

SS

DS

无无CS, ES, SS

无CS, DS, ES

CS, ES, SS

IP

SP

SI

DI

有效地址 EA

有效地址 EA

7 、 对内存寻址方式的注解( 1 )在汇编后,指令中的变量名有具体的偏移地址所取代。 ( 2 )在寄存器相对寻址与相对基址变址方式中,位移量 disp 可以是符号常量或变量,汇编后为一个常数,若是变量,则取其偏移地址。( 3 )在 Microsoft 宏汇编 MASM ( Microsoft Macro Assembler )中,内存操作数可以采用多种书写形式:6[BX][SI] 、 [BX+6][SI] 、 [BX+SI+6]

( 4 )在 [ ] 中只能出现立即数和 BX 、 BP 、 SI 、 DI ,且 BX 和 BP 、 SI 和 DI 不能成对出现在 [ ] 中。 如: [BX+BP] 、 [SI+DI] 是非法的指令形式

( 5 )计算出的有效地址以 16 位表示,若超过 0FFFFH ,CPU 将忽略所有溢出。 ( 6 )记忆 8086 内存操作数形式的简易方法如下: [BX] [SI] disp [BP] [DI]每列选择一项、二项或三项,即可得到有效的内存操作数形式。

四、端口寻址方式 操作数在端口寄存器中,指令中给出了端口的地址。根据端口地址的不同,有两种寻址方式:

1 、端口直接寻址 端口为 8 位地址 00H——FFH 如: IN AL , 80H ; 8 位数据 IN AX , 80H ; 16 位数据 OUT 81H , AL

2 、端口间接寻址 端口为 16 位地址 0000H——FFFFH 如: MOV DX , 218H IN AL , DX

源操作数的寻址方式例 源操作数的允许形式 直接操作数(立即数) MOV AX, 20H 指令中的直接常数

间接操作数

寄存器操作数 MOV AX, BX 通用寄存器或段寄存器

存储器操作数

直接寻址 MOV AX, DS:[20]MOV AX, B( 字 )

“ 段: [ 常数 ]” 或“段:常数”“[ 变量 ]” 或“变量”

间接寻址

寄存器间接寻址 MOV AX, [BX] [BX, BP, SI, DI 之一 ]

寄存器相对寻址 MOV AX, [BX+20] MOV AX, [BX+B( 字 )]

[BX, BP, SI, DI 之一+位移量 ]

基址变址寻址 MOV AX, [BX+SI] [BX, BP 之一+ SI, DI 之一]

基址变址相对寻址 MOV AX, [BX+SI+20] MOV AX, [BX+SI+B( 字 )]

[BX, BP 之一+ SI, DI 之一+位移量 ]

端口操作数

直接寻址 IN AL, 20H 指令中有端口号 (0 ~ 0FFH)

间接寻址 IN AL, DX DX 中有端口号 (0 ~ 0FFFFH)

操作数的寻址方式

§3.2 指令的机器码表示方法(略)

§3.3 8080 指令系统

8086/8088 的指令系统可以分为 6组:

( 1 )数据传送指令( 2 )算术运算指令( 3 )逻辑指令与移位指令( 4 )串操作指令( 5 )控制转移指令( 6 )处理机控制指令

一、 数据传送指令 数据传送指令是最简单、最常用的一类指令,它是负责把数据、地址、或立即数传送到寄存器或存储单元中 。这类指令又可分为以下几种情况 :

通用传送指令: MOV 、 PUSH/POP 、 XCHG 、 XLAT输入输出指令: IN 、 OUT地址目标传送指令: LEA 、 LDS 、 LES标志传送指令: LAHF 、 SAHF 、 PUSHF 、 POPF

1 、通用传送指令

( 1 ) MOV ( Move ):传送指令MOV 指令的格式为:MOV dest , src ; dest←src功能:将源操作数 src复制到目的操作数 dest 中,源操作数 src 的内容不变。对标志位的影响:无语法格式:MOV reg/mem/seg , reg/mem/seg/imm

MOV 指令的操作数及传送方向见下页

立即数 IMM

存储器MEM

通用寄存器REG

DS 、 ES 、 SSCS ( SEG )

说明:①双操作数指令不允许两个操作数同时为段寄存器或存储器操作数 MOV seg , seg ;错误 MOV mem , mem ;错误

② 立即数不能传送到段寄存器中 MOV seg , imm ; 错误

③ 立即数不能作为目的操作数 MOV imm , reg ; 错误

④目的操作数不允许使用 CS 、 IP 寄存器 MOV CS , AX ; 错误

⑤dest 与 src 必须类型匹配,即同时是字节或字类型。 MOV AX , BX注意:•寄存器具有明确的类型,例如, AL 、 AX 分别为字节、字类型。•立即数没有明确的类型, MASM负责将立即数扩展为与目的操作数位数相同。 MOV AL , 34H MOV BX , 56H•有时 MASM 不能确定内存操作数的类型,需要用 byte ptr 和 word ptr 明确指出是字节或字类型。只要其中一个操作数的类型确定即可。 MOV [2000H] , AL MOV [2000H] , BYTE PTR 34H

例:错误的 MOV 指令如下所示:MOV AX , BL ;类型不匹配MOV DS , 1000H ;不允许立即数送段寄存器MOV [BX] , [SI] ;不允许内存操作数之间传送MOV ES , CS ;不允许段寄存器之间传送MOV CS , AX ; CS 不能作为目的操作数

例:设 B 是已定义的字节变量,以下是一些错误和正确的指令。MOV AX , B ;错误,类型不匹配MOV B , 0 ;正确, MASM 可以判断出要 送字节 0 到单元 B 中MOV [BX] , 1 :错误,不能确定数据类型MOV BYTE PTR [BX] , 1 ;正确

( 2 ) XCHG ( Exchange ):交换指令XCHG 指令的格式为:XCHG oprd1 , oprd2 ;交换 oprd1 与 oprd2 的内容语法格式为:XCHG reg/mem , reg/mem

例:设数据段中有两个字变量 W1 和 W2 ,将这两个数据互换的程序段如下:MOV AX , W1XCHG AX , W2MOV W1 , AX

不用数据交换指令,仅用 MOV 指令的程序段如下:MOV AX , W1MOV BX , W2MOV W1 , BXMOV W2 , AX

还可以用堆栈操作指令来实现,程序段如下:PUSH W1PUSH W2POP W1POP W2

若 W1 、 W2 为字节操作数,则前两种方式均可行(用8 位寄存器),但不能用堆栈操作指令实现,因为堆栈操作只能是字操作。

( 3 ) PUSH :入堆操作 PUSH REG/MEM/SEG

操作:( SP ) ( SP ) -2 ,

(( SP ) +1 ,( SP )) ( SRC )

即先移后入。

( 4 ) POP :出栈 操作 POP REG/MEM/SEG

操作:( DST ) (( SP ) +1 ,( SP ))

( SP ) ( SP ) +2

先出后移。但 CS 不能作为目的操作数。

堆栈

SS : 01F8SS : 01FASS : 01FCSS : 01FE

SP

AA BB

(执行 PUSH AX 之前)

堆栈

SS : 01F8SS : 01FASS : 01FCSS : 01FE

SP

AA BB

(执行 PUSH AX 之后)

1101H 1101H

AX

堆栈SS : 01F8SS : 01FASS : 01FCSS : 01FE

SP

AA BB (执行 POP AX 之后)

1101H

AX

1 2

3

( 5 ) XLAT 查表指令

格式: XLAT ; [BX+AL] AL

功能:将表首地址为 BX ,偏移地址为 AL 的单元的内容送到AL 中。该指令通常用来实现一种代码向另一种代码的转换。

十进制数 七段代码 十进制数 七段代码

0 40H 5 12H

1 79H 6 02H

2 24H 7 78H

3 30H 8 00H

4 19H 9 18H

例:若十进制数字 0-9 的 LED七段代码对照表如前所示,试用求数字 5 的七段代码。

TABLE DB 40H , 79H , 24H , 30H , 19H

DB 12H , 02H , 78H , 00H , 18H

方法 1 : MOV AL , 5

MOV BX , OFFSET TABLE

XLAT

方法 2 : MOV SI , 5

MOV BX , OFFSET TABLE

MOV AL , [BX+SI]

2 、输入输出指令

输入输出指令是用来实现 I/O 端口与 AX 之间的数据传送。根据端口地址的不同,又分为端口直接寻址和端口间接寻址两种。

( 1 ) IN ( INPUT )

格式: IN AL ,( PORT ); 8 位地址、 8 位数据

IN AX ,( PORT ); 8 位地址、 16 位数据

或: IN AL , DX ; 16 位地址、 8 位数据

IN AX , DX ; 16 位地址、 16 位数据

( 2 ) OUT ( OUTPUT )

格式: OUT DX , AL ;其余类同。

3 、地址目标传送指令

( 1) LEA:取有效地址

格式: LEA REG , MEM 功能:取源操作数地址的偏移量,并把它传送到

止的操作数所在的单元。要求:源操作数必须是一个存储器操作数,目标

操作数必须是一个除段寄存器以外的 16 位寄存器,通常是间址寄存器 SI 等。

LEA 指令与 MOV 指令的区别:

LEA SI , BUFF 指令是将标号 BUFF 的偏移地址送入寄存器中;

MOV SI , BUFF 指令是将标号 BUFF 所指存储单元的内容送入 SI 。

BUFF =

0

1

2

3

4

5

48

00

FE

FF

LEA SI , BUFF ;

执行后:( SI ) =0002H

MOV SI , BUFF ;

执行后:( SI ) =0048H

段起始地址

( 2 ) LDS :传送有效地址及数据段首址指令

格式: LDS reg16 , mem32 ;功能:将源操作数指定的存储单元中取 4 个字节,前两个字节送入指定寄存器,后两个字节送 DS 寄存器。

( 3 ) LES :传送有效地址及附加数据段指令格式: LES reg16 , mem32 ;功能:将源操作数指定的存储单元中取 4 个字节,前两个字节送入指定寄存器,后两个字节送 ES 寄存器。

说明:指令中源操作数必须是存储单元,从该单元开始的连续 4 个字节单元中,存放着一个变量的地址指针。

57H

13H

68H

24H

例:( DS ) =C000H ,( C2480H ) =1357H ,( C2482H ) =2468H

DS : 2480H

DS : 2481H

DS : 2482H

DS : 2483H 13 57

24 68

SI

DS

LDS SI , [2480]

LDS 指令例

• DS = 6000H

• DI = 1234H

• AX = 2233H

12H34H

00H60H

1200H 数据段 1

DS

60 00 12 34

DI

数据段2

33H22H

61234H

4. 标志传送(位操作)指令

LAHF

SAHF

PUSHF

POPF

隐含操作数 AH

隐含操作数 FLAGS

LAHF , SAHF

( 1 ) LAHF ;将 FLAGS 的低 8 位装入 AH

( 2 ) SAHF ; 执行与 LAHF 相反的操作

SF PFAFZF CF

….AH

FLAGSD15 D0

D7 D0

例:标志寄存器传送。执行前:( FLAGS ) =0485H ,( AX ) =0FFFFH执行指令 LAHF 后, ( FLAGS ) =?

( 3 ) PUSHF

功能:将标志寄存器的内容进栈,同时修改 SP 。

( 4 ) POPF

功能:把当前 SP 所指的字送到标志寄存器 PSW ,并修改 SP 的值。

标志传送指令说明:

•LAHF/SAHF 指令是寄存器 AH 与标志寄存器 PSW 的低字节之间完成的字节型数据传送。• PUSHF/POPF 指令是标志寄存器 PSW 与堆栈间进行的字型数据传送。•指令 SAHF/POPF 将影响标志位。所有的数据传送类指令仅此两条指令影响标志位。

二、 算术运算指令

运算的数据类型:有符号二进制数、无符号二进制数、无符号压缩 BCD 码、无符号非压缩 BCD 码。

除 CBW 、 CWD外,所有指令均影响标志位。

指令类型:

加法: ADD 、 ADC 、 INC

减法: SUB 、 SBB 、 DEC 、 NEG 、 CMP

乘法: MUL 、 IMUL

除法: DIV 、 IDIV

符号扩展: CBW 、 CWD

十进制调整: DAA 、 DAS 、 AAA 、 AAS 、 AAM 、AAD

1 、加法指令指令格式:

加法 ADD DST , SRC ;( DST ) ( SRC ) + ( DST )

带进位加法 ADC DST , SRC ;

( DST ) ( SRC ) + ( DST ) +CF

加 1 INC DST ;( DST ) ( DST ) +1

说明:①这在三条指令运算结果将影响状态标志位,但是 INC指令不影响标志 CF 。

②SRC 可为 IMM 、 MEM 、 REG ,而 DST 只能为REG 、 MEM 类型。

③ 加法指令也有数据传送的功能,所以前面数据传送指令的限制同样有效。如不能同时为存储器操作数

例:将 3 个 32 位无符号数 12345678H , 8765ABCDH和 2468FEDCH 相加,其和(仍为 32无符号位数)送DX 和 AX 的程序段如下:

MOV DX , 1234H

MOV AX , 5678H

ADD AX , 0ABCDH

ADC DX , 8765H

ADD AX , 0FEDCH

ADC DX , 2468H

注意:字母开头的十六进制数,要在其前面加一数字 0

④对 INC 指令, DST既是源操作数,又是目的操作数,因此 DST 只能是 REG 或 MEM ,为 MEM 操作数时,必须指明数据类型,否则出错。

如: INC [SI] ;错误

应为: INC WORD PTR [SI] ;字内容加 1

INC BYTE PTR [SI] ;字节内容加 1

2 、减法指令指令格式:

减法 SUB DST , SRC ;( DST ) ( DST ) - ( SRC )

带进位减法 SBB DST , SRC ;( DST )( DST ) - ( SRC ) -CF

减 1 DEC OPR ;( OPR ) ( OPR ) -1

求补 NEG OPR ;( OPR ) 0FFFFH- ( OPR )+1

比较 CMP OPR1 , OPR2 ;( OPR1 ) - ( OPR2 )

以上五条指令均可作字或字节运算,而且除 DEC 不影响 CF外,其他都按一般规则影响状态标志位 。

说明:

①减法指令的语法规范同加法指令一致

② 求补指令不是求补码指令,它对任何形式的数均求补。如 AL=0AH , NEG AL 后, AL=F6H 。所以NEG 指令常用来求负数(补码形式)的绝对值

③比较指令除了不回送结果外,其他一切均同 SUB指令,该指令主要用来判断两数的大小与是否相等。比较指令后面常常是条件转移指令,根据比较的结果实现程序的转移。

④SBB 指令常用在多精度数的减法运算。

例: 34124275H-2F65E2A5H=? 34 124 275 -2F65E2A5 04AC4FD0程序段: X DW 4275H , 3412H Y DW 0E2A5H , 2F65H Z DW 0 , 0 … MOV AX , X SUB AX , Y MOV Z , AX MOV AX , X+2 SBB AX , Y+2 MOV Z+2 , AX

3 、乘法指令指令格式:

无符号数乘法 MUL SRC ;( AX )( AL ) * ( SRC )字节乘法

;( DX , AX )( AX ) * ( SRC )字乘法

带符号数乘法 IMUL SRC ;操作同上

进行字节运算时,目的操作数必须是累加器 AL ,乘积在寄存器AX 中;进行字运算时,目的操作数必须是累加器 AX ,乘积在寄存器 DX , AX 中。源操作数不允许使用立即数。

乘法指令运算结果只影响状态标志 CF 、 OF 。例: MUL BX ;无符号数乘法, BX乘上 AX

例 : 编程求 Y=5X ,假定 X 为字节数。

MOV AL , X

MOV BL , 5

MUL BL

MOV AL , 5

MUL X

4 、除法指令指令格式:

无符号数除法 DIV SRC ;( AL ) ( AX ) / ( SRC )除法的商

( AH ) ( AX ) / ( SRC )除法余数

或者 ( AX )( DX , AX ) / ( SRC )除法的商

( DX )( DX , AX ) / ( SRC )除法余数

带符号数除法 IDIV SRC ;操作同上。

•当除数是字节数据时,被除数必须放在 AX 中;当除数是字数据时,被除数必须放在 DX , AX 中。•除法指令运算结果对状态标志无定义。•8086/8088规定 IDIV 指令运算结果余数的符号与被除数相同。•带符号数除法运算中,当被除数位数不够时,可进行扩展。

符号扩展指令:

字节扩展到字 CBW ;将寄存器 AL 中的符号位扩展到寄存器 AH

字扩展到双字 CWD ;将寄存器 AX 中的符号位扩展到寄存器 DX

指令功能: ① 如果( AL )< 80H ,则( AH ) =00H (正数) 否则( AH ) =0FFH (负数) ② 如果( AX )< 8000H ,则 DX=0000H (正数) 否则( DX ) =0FFFFH (负数)

7 0AL7 0AH

015 AXDX15 0

CBW

CWD

例:求 -4001H÷4=?

MOV AX , -4001HCWDMOV CX , 4IDIV CX

说明:此题不能用 16 位除 8 位的方式,因为其商超过了 256 。

5 、压缩 BCD 码十进制调整指令

加法十进制调整 DAA ;

执行的操作:这条指令执行前必须先执行 ADD 或 ADC指令,加法指令必须把两个压缩的 BCD 码相加,并把结果存放在 AL 寄存器中。 减法十进制调整 DAS ;

执行的操作:这条指令执行之前,必须先执行 SUB 或 SBB 指令,减法指令必须把两个 BCD 码相减,并把结果存放在 AL 寄存器中。

调整的方法:•累加器 AL 低 4 位大于 9 或辅助进位标志位 AF=1 ,则累加器AL 加 06H修正。•累加器 AL 高 4 位大于 9 或辅助进位标志位 AF=1 ,则累加器AL 加 60H修正。•累加器 AL 高 4 位大于等于 9 ,低 4 位大于 9 ,则累加器 AL进行加 66H修正。

例:进行 BCD 码加法运算 59+68=127

0101 1001 59

+ 0110 1000 68

1100 0001 C1

+ 0110 0110 66

10010 0111 127

加法运算结果为 C1 ,

AF=1 ,高位大于 9

加 66H进行压缩 BCD调整

说明:•压缩 BCD 码加法或减法十进制调整指令必须在 ADD ( ADC )或 SUB ( SBB )指令之后,调整结果对标志 OF无影响,对其它状态标志位均有影响。•减法十进制调整方法与加法十进制调整方法类同,只是将加 6变为减 6 操作。

上述加法及调整的指令如下:

MOV AL , 59H

ADD AL , 68H

DAA

练习:求 83- 38=?(用 BCD 码实现)

6 、非压缩 BCD 码十进制调整指令

指令格式:

加法十进制调整 AAA ;

减法十进制调整 AAS ;

乘法十进制调整 AAM ;

除法十进制调整 AAD ;

AAA 指令将 AL 的内容变换成一位非压缩的十进制数。 AAA检查 AL 低四位,如低四位是 0--9 的数字, AAA就清除 AL 的高四位,以及 AF 和 CF 标志;如 AL 低四位表示的数大于 9 或AF=1 , AAA 执行:•加 6 到 AL 寄存器;•加 1 到 AH 寄存器;•置 AF=1 , CF=1 ;•清除 AL 高四位为 0

例:求 7+8=?MOV AX , 0007HMOV BL , 08HADD AL , BLAAA ;结果 AL=05H , AH=01H , CF=AF=1 。

AAS 指令检查 AL 低四位,如低四位表示的数是 0-9的数字, ASS清除 AL 高四位及 CF 和 AF 标志;如AL 低四位表示的数大于 9 或 AF=1 , AAS进行如下调整:AL减去 6 ;

AH减去 1 ;

置 AF=1 , CF=1 ;清除 AL 中高四位。

例:求 13- 4=?MOV AX , 0103HMOV BL , 04HSUB AL , BL ; AL=FFHAAS ; AL=09H , AH=0

AAM :指令的作用是用 10 ( 0AH )来除 AL 寄存器的内容,并将除得的商和余数分别送到 AH 和 AL 来实现转换。

例: 7×9=?MOV AL , 07HMOV BL , 09HMUL BL ; AX=003FHAAM ; AH=06H , AL=03H

AAD (非压缩 BCD 码除法调整)指令格式: AAD指令功能:在做除法之前,将 AL 加 AH*10 , AH清0进行调整。然后与非压缩 BCD 码作除法, AL 中得到正确的商, AH 中得到正确的余数。

例: 73÷2=? MOV AX , 0703H MOV BL , 02H AAD DIV BL ; AL=24H , AH=01H AAM ; AH=03H , AL=06H

以上几条指令的执行结果为:在 AX 中得到正确的商(非压缩 BCD 码),但余数丢失。如果需要保留余数,则应在 DIV 指令之后, AAM 之前,将余数暂存到一个寄存器。如果有必要,还应对余数进行调整。

三、 逻辑运算与移位指令

1 、逻辑运算指令:对字节或字数据进行按位的操作。格式:

逻辑与 AND DST , SRC ; ( DST )( DST ) AND ( SRC )

逻辑或 OR DST , SRC ; ( DST )( DST ) OR ( SRC )

逻辑非 NOT OPR ; ( OPR )( OPR )

异或 XOR DST , SRC ; ( DST )( DST ) XOR ( SRC )

测试 TEST OPR1 , OPR2 ;( OPR1 ) AND ( OPR2 )

AND 指令主要用于使操作数的某些位保留(和 1 相与)、某些位清 0 (和 0 相与)。

例: AND AL , 0FH ;屏蔽高 4 位,保留低 4 位。 OR 用法: a 用于使操作数的某些位保留(和 0 相或),某些位置 1 (和 1 相或)。 b 用于分离符号标志,进行判断、转移。影响 ZF 、SF 和 PF , CF=OF=0 。例: OR BX , 0C000B

将 BX 的两位最高的有效位( 15 和 14 位)置成 1 ,而其它位不变。

XOR 用法:用于使操作数的某些位保留(与 0异或),某些位取反(和 1异或)。

例:将 AL 的高 4 位保留,低 4 位取反: XOR AL , 0FH

例:将 AX 中的内容清 0 : XOR AX , AX

NOT 指令改变寄存器或存储单元的每一位状态,原来为 0 变为 1 ,原为 1 变为 0 。

例: NOT AX ; AX 各位取反

TEST 指令是一条测试指令,它执行的操作与 AND 相同,不过它不送回结果,只影响标志位。

例: TEST AL , 0000 0001B ;如 AL 最低位为 0 ,则 ZF=1 。

例:测试 AL 的 0 、 3 、 5 位,若有一位为 1 ,则转出错处理。

TEST AL , 00101001B

JNZ ERROR ; ZF=0 ,转出错 ERROR 。

2 、移位指令

逻辑左移 SHL OPR , CNL

算术左移 SAL OPR , CNL

逻辑右移 SHR OPR , CNL

算术右移 SAR OPR , CNL

其中: OPR 为操作数, CNL 为 1 或 CL 表示移位次数

0CF OPR

0

CFOPR

CFOPR

例:设 AL=1011 0100 , CF=1

在 SHL AL , 1 之后, AL= 0110 1000 CF=1

在 SAL AL , 1 之后, AL= 0110 1000 CF=1

在 SHR AL , 1 之后, AL=0101 1010 CF=0

在 SAR AL , 1 之后, AL=1101 1010 CF=0

算术左移( SAL )和算术右移( SAR )实现带符号数移位。SAR 通过在整个移位过程中复制符号来保护操作数的符号。 SAL 不保护进位,但如果符号位发生变化的话,就将 1 送 OF标志。在多次移位的情况下, OF 的值不确定。

逻辑左移( SHL )和逻辑右移( SHR )对无符号数的移位。SHL 将操作数左移,空出来的第 0 位置 0 ;

SHR 将操作数右移,空出来的高位(字节时第 7 位,字时第 15 位)置 0 。

例:将两个非压缩 BCD 码(高位在 BL ,低位在 AL )合并成压缩 BCD 码送 AL 。

MOV CL , 4 ;将计数值送 CL

SHL BL , CL ;将高位移到 BL 的高 4 位

AND AL , 0FH ;清零 AL 高 4 位

OR AL , BL ;合并 AL 和 BL 形成压缩 BCD 码。

例:用左移的方法实现 Y=5X

MOV AL , X

MOV CL , 2

SHL AL , CL ; AL=4X

ADD AL , X

例:用右移方法作除法 -128/8=-16

MOV AL , -128

MOV CL , 03H

SAR AL , CL

执行后, AL=0F0H=-16

3 、循环移位指令

循环左移 ROL OPR , CNT

循环右移 ROR OPR , CNT

带进位循环左移 RCL OPR , CNT

带进位循环右移 RCR OPR , CNT

CF OPR

CFOPR

CF OPR

CFOPR

例:设 AL=1011 0100B , CF=1 执行下列语句:

执行 ROL AL , 1 后, AL=0110 1001 , CF=1

执行 ROR AL , 1 后, AL=0101 1010 , CF=0

执行 RCL AL , 1 后, AL=0110 1001 , CF=1

执行 RCR AL , 1 后, AL=1101 1010 , CF=0

课堂练习:

1 、将 AL 寄存器的高 4 位与低 4 位交换。

2 、将 AL 中存放的压缩 BCD 码转换成非压缩 BCD 码并存放在 AX 寄存器中。

四、串操作指令串操作:对存储区中连续存放的字节或一串字进行操作。串操作指令的对象是内存中地址连续的字节或字串,在每次操作执行后,能自动修改地址,为下次操作作准备。如用重复前缀,则可一直执行直到预定的次数。串操作指令共有 5 条: MOVS 、 LODS 、 STOS 、 CMPS 和 SCAS 。( 1 )特点:①源操作数由 SI 间址,在当前数据段 DS中;目的操作数由 DI 间址,在附加数据段 ES 中,且不允许段超越。

② 每次操作后, SI 、 DI 的内容自动修改。 DF=0 : SI 、 DI 自动加 1 (或 2 ); DF=1 : SI 、 DI 自动减 1(或 2 )。③ 要处理的串长度存放在 CX 寄存器中,有的操作可使用重复前缀。而有的操作则不能使用(如 LODS )。( 2 )重复的方式: REP 无条件重复 REPE/REPZ 相等 / 结果为 0 则重复 REPNE/REPNZ 不相等 / 结果不为 0 则重复与 REP 前缀相配合工作的指令 MOVS 、 LODS 和 STOS 指令,直到( CX ) =0 为止。执行过程:① 如( CX ) =0 则退出 REP ,否则继续执行;② ( CX )←( CX )- 1 ;③ 执行其后的串指令;④ 重复① ~③。

1 、 MOVS (串传送)指令格式: [REP] MOVSB/MOVSW指令功能: DS : [SI]→ES : [DI]例;将数据段首地址为 BUF1 的 200 个字节传送到附加段首址为 BUF2 的内存区中,使用如下指令: MOV AX , SEG BUF1 MOV DS , AX MOV BX , SEG BUF2 MOV ES , BX LEA SI , BUF1 LEA DI , BUF2 MOV CX , 200 CLD LOP : MOVSB REP MOVSB LOOP LOP HLT

若不用串操作指令,可用一般指令编制如下: LEA SI , BUF1 LEA DI , BUF2 MOV CX , 200LOP : MOV AL , [SI] MOV [DI] , AL INC SI INC DI DEC CX JNZ LOP HLT

由此可看出,串操作指令是程序设计的高级技术。

2 、 LODS (串装入)指令格式: LODSB/LODSW指令功能:将 DS : [SI] 所指单元的内容装入 AL 或 AX 中。一般不用 REP 。无意义。

3 、 STOS (串送存)指令格式: [REP] STOSB/STOSW指令功能:将 AL 或 AX 中的内容送入 ES : [DI] 所指单元中。如用 REP ,则表示每个单元的内容完全相同。

例:将内存中以 BUF 为首址的 100 个字节单元的内容清 0 MOV AX , SEG BUF MOV ES , AX LEA DI , BUF XOR AX , AX MOV CX , 50 CLD REP STOSW HLT

注意要给 ES赋值

4 、 CMPS (串比较) 指令格式: [REPE/REPNE] CMPSB/CMPSW 指令功能: DS : [SI]- ES : [DI] , SI 、 DI 自动增加(减少)。 影响 SF 、 ZF 、 AF 、 PF 、 CF 和 OF 。

例:比较两个字符串,找出其中第一个不相等字符的地址。如果这两个字符串全部相同,则转到 ALLMATCH 处理。字符串长度均为 20 ,首地址分别为 STRING1 和 STRING2 。

程序如下: LEA SI , STRING1 LES DI , STRING2 MOV CX , 20 CLD REPE CMPSB JCXZ ALLMATCH DEC SI 不相等,但地址已加 1 (指向下 一个字符),故所求地址应修改 DEC DI HLT ALLMATCH : MOV SI , 0 MOV DI , 0 HLT

5 、 SCAS (串扫描)指令格式: [REPE/REPNE] SCASB/SCASW指令功能:在一个字符串中搜索指定的关键字。字符串起始地址在 ES : [DI] 中。不允许使用段超越。待查关键字在 AL 或 AX 中。

例:在包含 100 个字符的字符串中寻找第一个回车符CR (其 ASCII 码为 0DH ),找到后将其地址保留在 ES : DI 中,并在屏幕中显示“ Y” ;如果没有找到,则在屏幕上显示“ N” 。该字符串的首地址为 STRING

LEA DI , STRING MOV AL , 0DH MOV CX , 100 CLD REPNE SCASB JZ MATCH MOV DL ,‘ N‘ JMP DISPMATCH : DEC DI ;由于搜索时地址已加 1 ,故原地址应还原。 MOV DL ,‘ Y‘DISP : MOV AH , 2 INT 21H HLT

串操作指令的重复前缀、操作数和地址指针见下表:

指令 重复前缀 操作数 地址指针

MOVS REP 目的,源 ES:DI,DS:SI

LODS 无 源 DS:SI

STOS REP 目的 ES:DI

CMPS REPE/REPNE 源,目的 DS:EI,ES:DI

SCAS REPE/REPNE 目的 ES:DI

五、 控制转移指令

控制转移指令可分为以下几类:•无条件转移和过程调用: JMP 、 CALL 、 RET

•条件转移指令: JP/JNP 、 JS/JNS 、 JZ/JNZ 、 JO/JNO 、 JC/JNC 、 JG/JGE 、 JL/JLE 、 JA/JAE 、 JB/JBE

•循环控制指令: LOOP 、 LOOPE 、 LOOPNE 、 JCXZ

•中断控制指令: INT 、 INTO 、 IRET

1.无条件转移和过程调用指令

转移可以分成两类:段内转移( NEAR )和段间转移( FAR )。

段内转移:是指在同一段的范围之内进行转移,此时只需改变 IP 寄存器的内容,即用新的转移目标地址代替原有的 IP 的值就可达到转移的目的。

段间转移:则是要转到另一个段去执行程序,此时不仅要修改 IP 寄存器的内容,还需要修改 CS 寄存器的内容才能达到目的,因此此时的转移目标地址应由新的段地址和偏移地址两部分组成 。

直接转移:目的操作数用一个标号来表示。

间接转移:目的操作数放在某个 16 位寄存器或存储器单元中。

( 1 )段内直接转移: 形式: JMP SHORT LABEL ;段内短转移 JMP LABEL 段内直接转移 JMP NEAR PTR LABEL说明: SHORT 为短转移(- 128~ +127 ), NEAR PTR 为近转移( 16 位位移量)。但 MASM5 可自动识别其位移量,并加以区分。如下程序中,三种转移方式最终机器指令均为 EBFB 。

故一般常用的是 JMP LABEL 形式。

EB DISP-L DISP-H

E9 DISP-L

偏移量 机器码 程序 CODE SEGMENT ASSUME CS : CODE0000 0405 START : ADD AL , 05H0002 90 NOP0003 EBFB JMP SHORT START0005 90 NOP0006 CODE ENDS END START执行 JMP SHORT START 指令时, IP=0005H ,但由

于指令本身改变了 IP 的值, IP=0005+FB ( -5 ) =0000H ,故转移到 0000H 处开始执行。所以 DISP 的计算公式如下:

DISP= 目的地址偏移量- IP 的当前值

( 2 )段内间接转移: JMP REG16/MEM16说明:待转移的地址放在 16 位的寄存器( BX 、 BP 、

SI 、 DI )或内存单元中。

( 3 )段间直接转移: JMP FAR PTR LABEL说明: OFFSET LABEL→IP SEG LABEL→CS

( 4 )段间间接转移: JMP MEM32说明: MEM32 为内存单元中的地址,常用 DWORD P

TR 指明是对存储单元进行双字操作。执行时将低字内容送 IP ,高字内容送 CS 。

( 5 )段内直接调用: CALL 过程名( 6 )段内间接调用: CALL REG16/MEM16( 7 )段间直接调用: CALL FAR PTR 过程名( 8 )段间间接调用: CALL MEM32

例:设 CS=1200H , IP=0100H , SS=5000H , SP=0400H , DS=2000H , BX=0300H ,( 20300 ) =4800H ,( 20302 ) =00FFH ,说明下列指令执行后,程序分别转移到何处执行,并画出当前堆栈的示意图。( 1 ) JMP BX ( 2 ) CALL DWORD PTR [BX]

答:( 1 ) 1200 : 0300 ( 2 ) 00FF : 4800 。且将 CS 、 IP 分别入栈。所

以 SP=03FCH ,( SP ) =00H ,( SP+1 ) =01H ,( SP+2 ) =00H ,( SP+3 ) =12H ,

( 9 )返回指令: RET RET n指令功能:将堆栈中的内容分别弹出到 IP 和 CS 寄存器,从而使程序返回到原来调用过程的地方。 n 为弹出时舍去的字节数,常为偶数。

2 、条件转移指令 指令格式:操作符 短标号 位移量在﹣ 128~ +127 之间。即所有条件转移指令均为段内短转移。

( 1 )简单条件(直接标志)转移指令(共 10 条) 根据 CF 、 ZF 、 SF 、 OF 、 PF 分别为 1 或 0 ,共有 10 种状态,设置了 10 种转移指令:

JE/JZ JS JO JC JP ;标志为 1转移

JNE/JNZ JNS JNO JNC JNP ;标志为 0转

( 2 )无符号条件转移指令( 4 条)——间接标志转移 跟在 CMP 指令之后,根据结果确定转移方向。比较的对象视为无符号数。 JA (高于) JAE (高于等于) JB (低于) JBE (低于等于)

( 3 )有符号数条件转移指令( 4 条)——间接标志转移 JG (大于) JGE (大于等于) JL (小于) JLE (小于等于)

3 、循环控制指令( 1 ) LOOP 指令格式: LOOP LABEL 指令功能:将 CX 的内容减 1 ,若 CX≠0 ,则移到 LABEL 。 ( 2 ) LOOPE 指令格式: LOOPE LABEL 指令功能: CX-1→CX , CX≠0 且 ZF=1 ,转移。 ( 3 ) LOOPNE 指令格式: LOOPNE LABEL 指令功能: CX-1→CX , CX≠0 且 ZF=0 ,转移。 ( 4 ) JCXZ 指令格式: JCXZ LABEL 指令功能: CX=0 ,转移。

例:在一个由 17 个字符组成的字符串 STRING 中,现在查找该字符串中是否包含空格字符(其 ASCII 码为 20H ),若未找到或尚未查完,则继续查找,直到找到第一个空格字符或查完了才退出循环。

STRING DB ‘Personal Computer’ … MOV BX,OFFSET STRING DEC BX MOV CX,17 NEXT: INC BX CMP [BX] , BYTE PTR 20H LOOPNE NEXT …

方法二: MOV DI , OFFSET STRING MOV AL , 20H MOV CX , 17 REPNE SACSB JZ NEXT JMP NFOUND NEXT : … NFOUND :…

4 、中断指令INT n (中断调用) INTOIRET (中断返回)中断指令由于进入的方式比较复杂,故在后面章节中讲解。

六、处理机控制指令

1 、标志位操作指令 CLC (清 0 ) STC (置 1 ) CMC (取反) CLD STD CLI STI2 、外同步指令 HLT ;暂停, INTR 和 NMI 以及 RESET 可使 CPU退出暂停。 WAIT ;等待, /TEST信号使 CPU退出等待。 LOCK ;封锁总线,它是一种指令前缀,凡带有 LOCK 前缀的指令在执行过程中,将禁止其它处理器使用总线。 ESC ; 8086 对外 8087 的控制指令。

3 、空操作指令 NOP 不做任何操作,但占用 3 个时钟周期,然后执行下一条指令。如: MOV CX , 100 LOP : NOP LOOP LOP此例中 NOP 指令执行 100次,占用 300 个时钟周期。用这种方式可作软件延时。但由于机器的主频变化很大,因此,这种软件延时的方式不精确。通常用在对延时要求不高的场合。如 ADC0809转换结束后对数据的读取。

本章习题: 1 、 2 、 3 、 5 、 6 、 7 、 8 、 10 、 13 、 16 、 17