第三章 80x86 的指令系统

159
1 第第第 80x86 第第第第第第第 第第第第第第第第第第第 §3.1 80x86 第第第第 §3.2 80x86 第第第

description

第三章 80x86 的指令系统. 指令系统的特点及指令的基本格式 §3.1 80x86 寻址方式 §3.2 80x86 指令系统. 指令系统的特点及指令的基本格式. 一、概述 1. 程序语言简介 2. 8086/8088 指令简介. 一、概述 1. 程序语言简介 2. 8086/8088 指令简介. 1. 程序语言简介 1) 指令、指令系统和程序 2) 机器码和机器语言 3) 助记符和汇编语言 4) 高级语言. 1) 指令、指令系统和程序 CPU 是一个可以完成一些基本操作的电子器件。 - PowerPoint PPT Presentation

Transcript of 第三章 80x86 的指令系统

Page 1: 第三章  80x86 的指令系统

1

第三章 80x86 的指令系统

指令系统的特点及指令的基本格式

§3.1 80x86 寻址方式

§3.2 80x86 指令系统

Page 2: 第三章  80x86 的指令系统

2

一、概述 1. 程序语言简介 2. 8086/8088 指令简介

指令系统的特点及指令的基本格式

Page 3: 第三章  80x86 的指令系统

3

一、概述

1. 程序语言简介

2. 8086/8088 指令简介

Page 4: 第三章  80x86 的指令系统

4

1. 程序语言简介

1) 指令、指令系统和程序

2) 机器码和机器语言

3) 助记符和汇编语言

4) 高级语言

Page 5: 第三章  80x86 的指令系统

5

1) 指令、指令系统和程序

CPU 是一个可以完成一些基本操作的电子器件。

用编码表示 CPU 的一个基本操作,称为一条指令。

全部指令集称为指令系统。 指令系统反映 CPU 的基本功能,

是硬件设计人员和程序员能见到的机器的主要属性,

是硬件构成的计算机系统向外部世界提供的直接界面。

Page 6: 第三章  80x86 的指令系统

6

一个 CPU 的指令系统是固定的,

不同类型的 CPU 其指令系统不同 ;

同一系列向上兼容。

程序是为要解决的问题编写出来的指令集合。

用户为解决自己的问题所编写的程序称为源程序。

Page 7: 第三章  80x86 的指令系统

7

2) 机器码和机器语言

用二进制数编码表示的指令,称为机器指令或机器码。

机器语言是机器码及其使用的一组规则。

用机器语言编写的程序称为目标程序。

机器语言特点: CPU 能直接识别的唯一语言 面向机器,可直接被计算机执行 执行速度快,占用内存空间小 编程效率低、可读性差、可移值性差

应用:显示设备简单的单片机、家用电器、固化在 ROM 上的程序等

Page 8: 第三章  80x86 的指令系统

8

例 将地址为 2000H 和 2001H 的两内存单元内容相加, 结果存在地址 2002H 单元中,程序如下: A0 00 20

02 06 01 20A2 02 20

数据暂存器

PSW 标志寄存器 控制电路

指令译码器

AXBXCXDXSIDIBPSP

寄存器组

指令队列

总线接口控制电路

运算器

地址总线 AB

数据总线 DB

控制总线 CB

IP

地址加法器

DSES

SSCS

1010 00000000 00000010 00000000 00100000 01100000 00010010 00001010 00100000 00100010 0000

A0002002060120A20220

Page 9: 第三章  80x86 的指令系统

9

3) 助记符和汇编语言

助记符是有助记忆、并能描述指令功能的符号。 通常是指令功能的英文单词的缩写。

例 数的传送指令用助记符 MOV 加法用 ADD ,转移用 JMP 等

用助记符等表示的指令称为汇编格式指令例 MOV AL, 0

汇编语言是汇编格式指令、伪指令及其使用的一组规则。

用汇编语言编写的程序称汇编语言程序。

Page 10: 第三章  80x86 的指令系统

10

上例 将地址为 2000H 和 2001H 的两内存单元内容相加, 结果存在地址 2002H 单元中。

汇编格式指令与机器指令一一对应

用汇编语言编好的程序,

必须翻译成机器码表示的程序,计算机才能运行。

汇编程序是将汇编语言程序翻译成机器语言的一种系统程序。

用机器码编程: A0 00 20 02 06 01 20 A2 02 20

用汇编语言编写的确程序段为:MOV AL , var1ADD AL , var2MOV var3 , AL

Page 11: 第三章  80x86 的指令系统

11

汇编语言和机器语言编写的程序:面向机器,反映机器运行的实际过程 ,

与计算机的硬件结构和指令系统密切相关算法是用计算机的指令 , 寄存器等描述,

要了解 CPU 的编程结构、寻址方式、指令系统才能设计程序占内存少,执行速度快编写繁琐、调试困难

相对于机器语言编写的程序:

汇编语言程序,易读易懂,便于修改。

Page 12: 第三章  80x86 的指令系统

12

3) 高级语言

高级语言是独立于机器、面向过程或对象的语言。

算法是按照人的思维方式给出,比较接近人的自然语言。

上例 高级语言程序段为:

var3 = var1 + var2

由编译程序将高级语言源程序翻译目标程序,

即用机器码表示的程序,机器才能执行。(不同类型机器由于指令系统不同,它们的编译程序不同 )

Fortran、 Basic、 C 等均是高级语言。 使用高级语言编程,效率高,可读性、可移植性强。

Page 13: 第三章  80x86 的指令系统

13

2. 8086/8088 指令简介

指令格式

1) 操作码

2) 操作数

(1) 来源 (2) 个数 (3) 类型 (4) 执行速度

Page 14: 第三章  80x86 的指令系统

14

指令格式 操作码 操作数 例 ADD AL , 10H

数据传送算术运算逻辑运算串操作控制转移处理机控制

按功能指令分六类

1) 操作码

指明 CPU 要执行什么样的操作。是一条指令必不可少的部分,用助记符表示。

Page 15: 第三章  80x86 的指令系统

15

2) 操作数

指明参与操作的数据或数据所在的地方。

了解操作数的来源、个数、类型、执行速度。

指令格式 操作码 操作数 例 ADD AL , 10H

Page 16: 第三章  80x86 的指令系统

16

(1) 操作数来源 指明操作数所在的地方

有三种来源:

① 操作数在指令中,称立即数操作数 如 MOV AL , 9

② 操作数在寄存器中,称寄存器操作数指令中给出用符号表示的寄存器名。 如 MOV AL , 9

③ 操作数在内存单元中,称存储器操作数或内存操作数 指令中给出该内存单元的地址。用 [ ]表示存储器操作数

如 MOV AL , [ 2000H ]

Page 17: 第三章  80x86 的指令系统

17

(2) 操作数个数

按指令格式中,操作数个数的多少分为三类:

无操作数 : 指令只有一个操作码,没有操作数

单操作数 : 指令中给出一个操作数

双操作数 : 指令中给出两个操作数。

Page 18: 第三章  80x86 的指令系统

18

① 无操作数: 指令只有一个操作码,没有操作数。

有两种可能:

▲ 有些操作不需要操作数。

如 HLT, NOP 等处理机控制指令。

▲ 操作数隐含在指令中。

如 STC , CLC 等处理机控制命令。

AAA , DAA 等调整指令。

Page 19: 第三章  80x86 的指令系统

19

② 单操作数 : 指令中给出一个操作数。

有两种可能:

▲有些操作只需要一个操作数

如 INC AL ; ( AL) ← ( AL) + 1

▲有些操作将另一个操作数隐含在指令中

如 MUL BL ; ( AX) ← ( AL)×(BL)

Page 20: 第三章  80x86 的指令系统

20

③ 双操作数 : 指令中给出两个操作数。

如 ADD AL , BL ; (AL) ← (AL) + (BL)

目的操作数 源操作数

操作后的结果通常存放在目的操作数中。

Page 21: 第三章  80x86 的指令系统

21

3) 操作数类型

指令应指明参与操作的数是字节还是字,即操作数的类型。

通常操作数的类型可由操作数本身隐含给出。

只在特殊情况下需要指明。

8086/8088:

有的操作既可对字节操作,又可对字操作

有的操作只允许对字操作

Page 22: 第三章  80x86 的指令系统

22

① 指令中有寄存器操作数,由寄存器操作数决定类型。

例 : MOV [BX], AL ;字节操作 , [BX] ← AL

MOV [BX] , AX ;字操作 , [BX] ←AL, [BX+1] ←AH

D:\>DEBUG ; 进入 DEBUG-A ; 汇编指令1693:0100 MOV [BX], AL1693:0102 MOV [BX], AX1693:0104-U 100 ;返汇编指令 1693:0100 8807 MOV [BX], AL1693:0102 8907 MOV [BX], AX、、、、、、

在 DEBUG下查看指令对应的机器码:

两条指令的机器码不同 : 一个是 0788H, 另一个是 0789H

Page 23: 第三章  80x86 的指令系统

23

② 指令操作数中无寄存器,则由内存操作数的类型决定。

value 00H ….

内存

value 00H 00

H

例 value 是一个变量 ( 即内存操作数 );

若定义 value 为字节类型 :

则 MOV value , 0 是字节操作。

若定义 value 为字类型 :

则 MOV value , 0 是一个字操作。

Page 24: 第三章  80x86 的指令系统

24

例 MOV [ BX ], 0

③ 指令中无类型的依据,需对存储器操作数加类型说明。

用 PTR 属性伪操作说明类型。MOV byte PTR [BX] , 0 字节操作, [ BX ] ← 0MOV word PTR [BX] , 0

字操作, [ BX ] ← 0, [ BX+1 ] ← 0

Page 25: 第三章  80x86 的指令系统

25

4) 执行速度

寄存器操作数 立即数操作数 存储器操作数

例 mov AL , BL

mov AL , 0 mov AL , [ BX ]

哪条指令执行速度快?

三条指令:

操作类型相同,都是传送指令 ,且目的操作数相同,

不同的是源操作数。

Page 26: 第三章  80x86 的指令系统

26

DSESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

mov AL , BLmov AL , 0 mov AL , [ BX ]

Page 27: 第三章  80x86 的指令系统

27

对同一类型指令,执行速度:

寄存器操作数 立即数操作数 存储器操作数

快 慢

例 mov AL , BL 快

mov AL , 0 mov AL , [ BX ] 慢

Page 28: 第三章  80x86 的指令系统

28

第一节、 8086/8088 的寻址方式

指明操作数的来源,即寻找(得到)操作数的方法。

共 7 种寻址方式:1. 立即数寻址2. 寄存器寻址3. 直接寻址4. 寄存器间接寻址 5 种与内存单元 5. 寄存器相对寻址 有关的寻址6. 基址加变址寄存器寻址 ( 存储器操作数 )

7. 相对基址加变址寄存器寻址

Page 29: 第三章  80x86 的指令系统

29

以数据传送指令 MOV 为例介绍寻址方式。

指令 MOV dst, src 执行 (dst ) ← ( src )

即: 源操作数的内容不变,

目的操作数 = 源操作数

Page 30: 第三章  80x86 的指令系统

30

一 . 立即数寻址

操作数在指令中,取来指令立即可得到操作数。

称该操作数为立即数。 立即数可以是 8 位或 16 位。

立即数常用来给寄存器或内存单元赋初值。

56B8

内存

20数作操

操作码

例 1 MOV AX , 2056H

结果 ( AH ) = 20H

( AL ) = 56H

例 2 MOV AL , 78 H

结果 ( AL ) = 78H

Page 31: 第三章  80x86 的指令系统

31

二 . 寄存器寻址方式

操作数在寄存器中,指令中指定寄存器名

8 位操作数, 用 8 位寄存器 :

AH 、 AL 、 BH 、 BL 、 CH 、 CL 、 DH 、DL

16 位操作数,用 16 位寄存器 :

AX 、 BX 、 CX 、 DX 、 SP 、 BP 、 SI 、 DI

CS 、 DS 、 SS 、 ES

Page 32: 第三章  80x86 的指令系统

32

例 1 MOV AX , 2056H

执行后: (AX)=2056H

例 2 MOV BL , AH

执行前: (BL) = 12H, (AH) = 78H

执行后: (BL) = 78H (AH) = 78H

Page 33: 第三章  80x86 的指令系统

33

▲ 立即数寻址、寄存器寻址的操作数, 不用在取完指令后再到内存中取数。

DSESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

Page 34: 第三章  80x86 的指令系统

34

三 . 存储器寻址▲以下的 5 中寻址方式, 操作数存放在内存中,取完指令后,还需到内存取数。 指令中给出的是该操作数的地址,包括段地址和偏移地址。 DS

ESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

Page 35: 第三章  80x86 的指令系统

35

例 编程将 CL 寄存器的内容传送到 21000H 单元中。

MOV AX, 2000H

MOV DS, AX ; (DS) = 2000H

MOV DI, 1000H ; (DI) = 1000H

MOV DS: [ DI ], CL ;(21000H) = (CL)

地址 21000H = 2000 : 1000H

编程时, DS 存放段地址 2000H

DI 存放偏移地址 1000H

如指令 MOV DS: [ DI ] , CL

完成将 CL 寄存器中的内容传送到以 DS 为段值, DI 为偏移值的内存单元中

Page 36: 第三章  80x86 的指令系统

36

数据暂存器

PSW 标志寄存器 执行部件

控制电路

指令译码器

AXBXCXDXSIDIBPSP

寄存器组

指令队列

总线接口控制电路

运算器

地址总线 AB

数据总线 DB

控制总线 CB

器21000H21001H21002H

IP

地址加法器

DSES

SSCSA0

通过例子看到:在相应的寄存器中设定段值和偏移值,由地址加法器送出 20 位的地址信号,对选中的内存单元进行操作。

1000

21000MOV AX, 2000H

MOV DS, AX

MOV DI, 1000H

MOV DS: [ DI ], CL

20002000

A0

Page 37: 第三章  80x86 的指令系统

37

内存单元的地址由段地址和偏移地址构成

▲ 为减短指令长度 指令中只给出偏移地址的来源,段地址由默认关系给出。 MOV AL , [ 2000H ]

▲ CPU 根据偏移地址给出的方式, 按默认关系自动选择段寄存器,获取段值, 由段值、偏移值构成操作数所在内存单元的物理地址。

上例 PA= ( DS ) ×10H + 2000H

即选择 DS 寄存器的内容为段地址。

Page 38: 第三章  80x86 的指令系统

38

指令中用 [ ] 给出偏移地址。 操作数的偏移地址又称有效地址 EA ( Efficient Address)

▲按给出偏移地址方式的不同,分为以下 5 种:

直接寻址 MOV AL, [ 1000H ]

寄存器间接寻址 MOV AL, [ BX ]

寄存器相对寻址 MOV AL, [ BX + 10H ]

基址加变址寄存器 MOV AL, [ BX + SI ]

相对基址加变址寄存器 MOV AL, [ BX + SI + 10H ]

另外, 80386 以上微处理器还有比例变址寻址基址比例变址寻址相对基址比例变址寻址

Page 39: 第三章  80x86 的指令系统

39

1 .直接寻址方式

存储器操作数的有效地址 EA 在指令中直接给出。

例 MOV AL, [ 1000H ]

默认段寄存器为 DS 。

操作数所在内存单元的物理地址为:

PA = ( DS )×10H + EA

Page 40: 第三章  80x86 的指令系统

40

直接寻址方式默认段寄存器为 DS

DSESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

Page 41: 第三章  80x86 的指令系统

41

例: MOV AX , [ 1000 H]

若 ( DS ) = 2000H

内存操作数的物理地址为:

PA = ( DS )×10H +EA

= 2000H × 10H + 1000H

= 21000H

执行后 (AX)= 3040H

21000 40

00A1

内存

10

30

指令

Page 42: 第三章  80x86 的指令系统

42

在汇编语言程序中,不直接用数值 表示偏移地址, 用符号代替数值表示地址,称符号地址 ( 变量名 ) 。

buffer 0A

0B

例 符号 buffer 表示一个地址。 MOV AX , [buffer]

或写成 MOV AX , buffer

源操作数为 buffer 指向的内存单元的内容

符号地址 ( 变量名 ) 经汇编连接后,与一个确定的数值地址相对应可用操作符 Offset 获取变量的偏移地址。

故 PA = ( DS )×10H + Offset buffer 指令执行结果 ( AX ) = 0B0A H

Page 43: 第三章  80x86 的指令系统

43

2. 寄存器间接寻址

存储器操作数的有效地址 EA 由寄存器给出 ,

寄存器的内容为操作数的有效地址。

可用的寄存器有 BX 、 SI 、 DI  、 BP

如 : MOV AL, [ BX ]

MOV AH, [ SI ]

MOV DL, [ DI ]

MOV DH, [ BP ]

Page 44: 第三章  80x86 的指令系统

44

默认段寄存器的关系:

①使用 BX 、 SI 、 DI ,默认段寄存器为 DS

(BX)

PA = ( DS )×10H + (SI)

(DI)

②使用 BP ,默认段寄存器为 SS

PA = ( SS )×10H + ( BP )

Page 45: 第三章  80x86 的指令系统

45

使用 BX 、 SI 、 DI 的寄存器寻址,默认段寄存器为 DS

DSESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

Page 46: 第三章  80x86 的指令系统

46

使用 BP 的寄存器寻址,默认段寄存器为 SS

DSESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

Page 47: 第三章  80x86 的指令系统

47

例: MOV AX , [ DI ]

若 ( DS ) = 3000H

( DI ) = 2000H

则内存操作数的物理地址为:

PA = ( DS )×10H + ( DI )

= 32000H

执行后 (AX) = (32000H) = 400BH

32000 0B

05

8B指 令

40

Page 48: 第三章  80x86 的指令系统

48

例: MOV AX , [ BP ]

若 ( SS ) = 4000H

( BP ) = 3000H

则内存操作数的物理地址为:

PA = ( SS )×10H + ( BP )

= 43000H

指令执行后 (AX) = (43000H) = 0102H

43000 02

46

8B指 令

01

Page 49: 第三章  80x86 的指令系统

49

3. 寄存器相对寻址

操作数的有效地址由一个寄存器与一个偏移量相加得到

偏移量(相对量)在指令中给出,范围在 0000 ~ FFFFH

可用的寄存器有 BX 、 DI  、 SI 、 BP , 与寄存器间接寻址相同

如 : MOV AL, [ BX +10H]

MOV AH, [ DI+20H ]

MOV DL, 30H [ SI ]

MOV DH, 40H [ BP ]

Page 50: 第三章  80x86 的指令系统

50

默认段寄存器的关系与寄存器间接寻址相同

①使用 BX 、 SI 、 DI ,默认段寄存器为 DS

(BX)

PA = ( DS )×10H + (SI) + 偏移量

(DI)

②使用 BP ,默认段寄存器为 SS

PA = ( SS )×10H + ( BP ) + 偏移量

Page 51: 第三章  80x86 的指令系统

51

例: MOV AX , [ BX+30H ]

若 ( DS ) = 2000H

( BX ) = 1000H

则内存操作数的物理地址为:

PA = ( DS )×10H + ( BX ) + 30H

= 21030H

指令执行后:

(AX) = (21030H) = 8976H

21030 76

30

47指 令

89

8B

Page 52: 第三章  80x86 的指令系统

52

例: MOV AX , 60H [ BP ]

若 ( SS ) = 3000H

( BP ) = 200H

则内存操作数的物理地址为:

PA = ( SS )×10H + ( BP ) + 60H

= 30260H

指令执行后:

(AX) = (30260H) = 0ABCH

30260 BC

60

46指 令

0A

8B

Page 53: 第三章  80x86 的指令系统

53

4. 基址加变址寻址

操作数的有效地址由 一个基址寄存器与一个变址寄存器之和给出。

可用的基址寄存器为 BX 、 BP

变址寄存器为 SI 、 DI

如 MOV AL , [ BX+SI ]

MOV AX , [ BX][DI ]

MOV DL , [ BP+SI ]

MOV DX , [ BP][DI ]

Page 54: 第三章  80x86 的指令系统

54

默认段寄存器由基址寄存器决定。

① 基址寄存器为 BX ,默认段寄存器为 DS

(SI)

PA = ( DS )×10H + ( BX ) +

(DI)

② 基址寄存器为 BP ,默认段寄存器为 SS

(SI)

PA = ( SS )×10H + ( BP ) +

(DI)

Page 55: 第三章  80x86 的指令系统

55

使用 BX 的基址加变址寻址,默认段寄存器为 DS

DSESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

Page 56: 第三章  80x86 的指令系统

56

使用 BP 的基址加变址寻址,默认段寄存器为 SS

DSESSSCS

IP

数据暂存器

PSW 标志寄存器 执行部件控制电路

指令译码器

AXBXCXDX

AHBHCHDH

SIDIBPSP

ALBLCLDL

寄存器组

指令队列

总线接口控制电路

运算器

地址加法器

、、、指令 1

指令 2

指令 3

指令 4

、、、数据 1

数据 2

数据 3

、、、

地址总线 AB

数据总线 DB

控制总线 CB

CPU 总线 内存

Page 57: 第三章  80x86 的指令系统

57

例: MOV AX , [ BX + SI ]

若 ( DS ) = 4000H

( BX ) = 2000H

( SI ) = 100H

则内存操作数的物理地址为:

PA = ( DS )×10H + ( BX ) + ( SI )

= 42100H

指令执行后

(AX) = (42100H) = 2345H

42100 45

00

8B指 令

23

Page 58: 第三章  80x86 的指令系统

58

5. 相对基址加变址寻址

操作数的有效地址由 基址寄存器、变址寄存器、偏移量三者之和给出。

可用的寄存器与基址加变址寻址方式相同 基址寄存器有 BX 、 BP

变址寄存器有 SI 、 DI

如 MOV AL, [ BX+SI +10H]

MOV AX , 20H[ BX][DI ]

MOV DL , [ BP+SI+30H ]

MOV DX , 40H[ BP][DI ]

Page 59: 第三章  80x86 的指令系统

59

默认段寄存器由基址寄存器决定 , 与基址加变址寻址相同

① 基址寄存器为 BX ,默认段寄存器为 DS

(SI)

PA = ( DS )×10H + ( BX ) + + 偏移量 (DI)

② 基址寄存器为 BP ,默认段寄存器为 SS

(SI)

PA = ( SS )×10H + ( BP ) + + 偏移量 (DI)

Page 60: 第三章  80x86 的指令系统

60

例: MOV AX , [ BX + SI + 10H ]

若 ( DS ) = 4000H

( BX ) = 3000H

( SI ) = 200H

则内存操作数的物理地址为: PA = ( DS )×10H + ( BX ) + ( SI ) + 10H

= 43210H

指令执行后 (AX) = (43210H) = 8877H

43210 77

10

40指 令

88

8B

Page 61: 第三章  80x86 的指令系统

61

寻址方式的几点说明

1 .偏移量可用符号地址给出

例: MOV AX , mask [ BX ]

若 ( DS ) = 1000H

( BX ) = 300H

OFFSET mask = 2000H

PA = ( DS ) × 10H + ( BX )

+ OFFSET mask

= 12300H

执行后 ( AX ) = 6B5A H

12300 5A

33

22

mask12000

6B

11

Page 62: 第三章  80x86 的指令系统

62

2. 段跨越前缀的使用

段跨越前缀

在指令中出现的指定内存单元段地址的段寄存器符号。

表示方法为 段寄存器名 :

例: MOV AX , ES : [ BX ]

ES : MOV AX , [ BX ] ( DEBUG 下格式)

为减小指令长度, CPU 采用默认关系获取段地址。

使用段跨越前缀可强行改变这种默认关系。

Page 63: 第三章  80x86 的指令系统

63

使用段跨越前缀的指令比不使用的指令要多占一个字节。

8B

07

指 令 MOV AX,ES:[BX]

26

指 令 MOV AX,[BX] 8B

07

Page 64: 第三章  80x86 的指令系统

64

使用段跨越前缀的物理地址计算

例: MOV AX , ES : [ BX ]

使用段跨越的前缀后,段地址由指定的段寄存器给出 ,

不再遵循默认关系。

PA = ( ES ) × 10H + ( BX )

而不等于≠ ( DS ) × 10H + ( BX )

Page 65: 第三章  80x86 的指令系统

65

只有存储器操作数需用段跨越的前缀

MOV ES : [SI] , CX

MOV AL , DS : [BP]

MOV ES : AX , 0

CS: MOV CX, 22H ;DEBUG

Page 66: 第三章  80x86 的指令系统

66

3 .不自创寻址方式 内存操作数地址只能由 BX 、 BP 、 SI 、 DI 给出 ,

它们的组合也不是任意的。

基址加变址

[ BX+SI ][ BX+DI][ BP+SI ][ BP+DI]

寄存器相对

[SI + X ][DI + X ][BX + X ][BP + X ]

寄存器间接

[SI ][DI ][BX ][BP ]

相对基址加变址[ BX+SI+X ][ BX+DI+X][ BP+SI+X ][ BP+DI+X]

X 为 8位或16位偏移量

Page 67: 第三章  80x86 的指令系统

67

除此之外,其他方式均错误。

如 MOV CL, [AX]

MOV AX, [DX]

MOV AL, [CX]

MOV CX, [BP+BX]

MOV AH, [SI+DI]

MOV BL, [AX+CX]

Page 68: 第三章  80x86 的指令系统

68

6 、比例变址寻址( 386 以上) EA = 变址 *比例因子 + 位移量

例如:设变址 (ESI)=2 ,比例因子 =4 ,则:MOV EAX , [ESI*4+12340H]

元 素0

元 素1

元 素2

数据段

……

12340H+0*4

12340H+1*4

变址 (ESI) : 2比例因子: 4

偏移量: 12340H+2*4=12348H

位移量: 12340H

AH ALEAX

12340H+2*4

Page 69: 第三章  80x86 的指令系统

69

7 、基址比例变址寻址 ( 386 以上) EA = 基址 + 变址 *比例因子

例如:基址 (EBP)=12340H ,变址 (ESI)=3 ,比例因子 = 2 ,则:MOV AX , [EBP+ESI*2]

元 素0元 素1元 素2

堆栈段

……

12340H+0*2

12340H+1*2

变址 (ESI) : 3比例因子: 2偏移量: 12340H+3*2=12346H

基 址 (EBP) : 12340H

AH ALAX

元 素3

12340H+1*2

12340H+3*2

Page 70: 第三章  80x86 的指令系统

70

8 、相对基址比例变址寻址 (386 以上 )

EA = 基址 + 变址 * 比例因子 + 位移量 例如:设基址 (EBX)=12340H ,变址 (EDI)=2 ,比例因子 =4 ,则:

MOV EAX , [EBX+EDI*4+12H]

元 素0

元素 1

元素 2

数据段

……

12340H+0*4+12H

12340H+1*4+12H

变址 (EDI) : 2比例因子: 4

偏移量: 12340H+2*4+12H=1235AH

位移量: 12H

AH ALEAX

12340H+2*4+12H

基址 (EBX) : 12340H

Page 71: 第三章  80x86 的指令系统

71

四、 I/O 端口寻址

直接端口寻址采用这种寻址方式时,端口地址只有 8位( 0~0FFH)。例如:

IN AL , 10H ;从 10H 号端口读入 8位数据OUT 50H , AX ;把 AX 中的内容送到 50H 号端口IN EAX , 20H ;从 20H 号端口读入 32位数据

Page 72: 第三章  80x86 的指令系统

72

I/O 端口寻址 间接端口寻址:采用这种寻址方式时,端口地址

为 16位( 0~0FFFFH)。 必须先将端口地址存放到寄存器 DX 中。

例如:MOV DX , 1000H;端口地址为 1000H

OUT DX , AL ;间接端口寻址

Page 73: 第三章  80x86 的指令系统

73

.壹 概述

.贰 数据传送指令

.叁 算术运算指令

.肆 逻辑运算指令

.伍 控制转移指令

.陆 处理机控制指令

.柒 串操作指令

第二节 80x86 指令系统

Page 74: 第三章  80x86 的指令系统

74

一.概述

1. 指令助记符表

2. 学习指令的要点

3. 利用 DEBUG 程序,学习指令系统

4. 指令中操作数的表示

5. 书写指令注意事项

Page 75: 第三章  80x86 的指令系统

75

指令类型 助记符通用传送 MOV, PUSH, POP, XCHG, XLAT

地址传送 LEA, LDS, LES

标志传送 PUSHF, POPF, LAHF, SAHF

数据传送 输入输出 IN, OUT

加法 ADD, ADC, INC, AAA, DAA

减法 SUB, SBB, DEC, NEG, CMP, AAS, DAS

乘法 MUL, IMUL, AAM

除法 DIV, IDIV, AAD

算术运算

符号扩展 CBW, CWD

逻辑运算 AND, TEST, OR, XOR, NOT

移位 SHL, SAL, SHR, SAR逻辑操作 循环移位 ROL, ROR, RCL, RCR

1. 指令助记符表

Page 76: 第三章  80x86 的指令系统

76

指令类型 助记符串操作 MOVS,CMPS,SCAS,LODS,STOS串

处理 重复控制 REP,REPE/REPZ,REPNE/REPNZ

无条件转移 JMP

条件转移

JE/JZ, JNE/JNZ, JS, JNS, JO, JNO

JP, JNP, JC, JNC, JCXZ

JA/JNBE, JAE/JNB, JB/JNAE, JBE/JNA

JG/JNLE, JGE/JNL, JL/JNGE, JLE/JNG

循环控制 LOOP, LOOPE/LOOPZ, LOOPNE/LOOPNZ

过程调用 CALL, RET

控制转移

中断指令 INT, INTO, IRET

处理机控制CLC, STC, CMC,CLD, STD, CLI, STI

NOP, HLT, WAIT, ESC, LOCK

Page 77: 第三章  80x86 的指令系统

77

2. 学习指令的要点

从以下几个方面来掌握一条指令 : 指令的助记符 指令的格式:操作数的个数、类型 执行的操作:指令执行后的结果包括 : 哪些寄存器、内存单元的值发生了变化

对标志位有无影响,哪些受影响 特点及注意事项

只介绍常用的指令,其他需要时可自学。

Page 78: 第三章  80x86 的指令系统

78

4. 指令中操作数的表示

符号 表示内容data 立即数操作数

reg通用寄存器操作数 8位:AH、AL、BH、BL、CH、CL、DH、DL

16位:AX、BX、CX、DX、BP、SP、SI、DIsegreg 段寄存器 CS、DS、SS、ESmem

或 [ ] 存储器操作数(5种寻址方式)

src 源操作数dst 目的操作数

( ) 寄存器、存储器、端口的内容oprd1oprd2

两操作数

Page 79: 第三章  80x86 的指令系统

79

5. 书写指令注意事项:

不区分字母的大小写。

下列写法表示同一条指令:

MOV AX, 1ABDH

mov ax, 1abdh

不添加指令系统没有的指令,即不自创助记符。

将 MOV AL , 0 写成 MOVE AL , 0

JMP lable 写成 JUMP lable

Page 80: 第三章  80x86 的指令系统

80

注意操作数的范围

对字节操作指令 0 ~ FFH 0 ~ 255

对字操作指令 0 ~ FFFFH 0 ~ 65535

MOV AL , 260 MOV AX , 70000 MOV AL, 1FFH MOV AL, 2ABCDH

Page 81: 第三章  80x86 的指令系统

81

对无操作数指令,不添加操作数。

STC AL

对单操作数指令,操作数不能是立即数。

IMUL 6

Page 82: 第三章  80x86 的指令系统

82

对双操作数指令

① 不能两个同为存储器操作数 MOV [ DI ] , [ SI ]

② 目的操作数不能是立即数 ADD 3 , AL ③ 两个操作数的类型应相同 SUB AX , BL

若 value 定义为字类型存储器变量:

MOV CL, value [ BX ]

Page 83: 第三章  80x86 的指令系统

83

内存操作数的属性应明确。

MOV [ BX ] , 0

MOV byte ptr [ BX ] , 0

MOV word ptr [ BX ] , 0

MOV [ BX ] , AL

MOV [ BX ] , AX

Page 84: 第三章  80x86 的指令系统

84

A 、 B 、 C 、 D 、 E 、 F 开头的十六进制数前面加 0 ,

与 H 结尾的标识符区别。

如 寄存器名 AH 、 BH 、 CH 、 DH

变量名 abcdH 等

例 mov AL, 0AH

mov AL, AH

mov BX, 0abcdH

Page 85: 第三章  80x86 的指令系统

85

CS 和 IP 的值只在控制转移指令中修改。

对非控制转移指令,取完指令后 IP 值自动 指向下条指令。

段寄存器 CS 的值,只在 MOV 、 PUSH 中可作操作数, 且这两条指令执行结果不改变 CS 值。

MOV AX, CS

PUSH CS

IP 、 PSW 两个寄存器不作为操作数在指令中出现。mov IP , 1234H

mov PSW , 0F0FH

PSW状态寄存器的值由指令执行后确定, 不同的指令对各标志的影响不同。

Page 86: 第三章  80x86 的指令系统

86

一 . 数据传送指令

存储器

I/O接口

输入设备

I/O接口

数据总线 DB

控制总线 CB

地址总线 AB

输入设备

CPU

寄存器,存储器, I/O 端口

Page 87: 第三章  80x86 的指令系统

87

▲ 数据传送是最基本、最重要的一种操作

实际程序中,使用的比例最高 change PROC LEA SI, num+2

MOV CL, num+1 MOV CH, 0 MOV AX, 0 MOV DI, 10

next: MUL DI MOV BH, 0 MOV BL, [SI] AND BL, 0FH ADD AX, BX INC SI LOOP next

zero: MOV BX, AX RET

change ENDP

汇编子程例:

寄存器 寄存器

寄存器 内存单元

寄存器 I/O端口

设置寄存器、内存单元的初始值

Page 88: 第三章  80x86 的指令系统

88

▲ 按传送内容,可分为四类:

1. 通用数据传送 MOV, PUSH, POP, XCHG, XLAT ,MOVSX,MOVZX,PUSHA,POPA

2. 地址传送 LEA, LDS, LES , LFS , LGS , LSS

3. 标志传送 PUSHF, POPF, LAHF, SAHF , PUSHFD , POPFS

4. 输入输出传送 IN, OUT

▲ 特点:

1. 除 POPF 、 SAHF 外,其他传送指令对标志位均无影响

2. 唯一允许以段寄存器做操作数的指令 且只有 MOV 、 PUSH 、 POP 这三条允许

Page 89: 第三章  80x86 的指令系统

89

1. 通用传送指令 MOV 、 PUSH 、 POP 、 XCHG 、 XLAT

reg/mem/segreg ← reg

reg/segreg ← mem

reg/mem ← segreg

reg/mem ← data

可实现

1 ) MOV 传送指令

格式 MOV dst , src

执行 ( dst ) ← ( src )

Page 90: 第三章  80x86 的指令系统

90

例 : ①reg/mem/segreg ← reg 通用寄存器 /存储器 /段寄存器←通用寄存器 MOV AL , BL MOV [ BX ] , AL MOV DS , AX

②reg/segreg ← mem 通用寄存器 /段寄存器 ← 存储器 MOV AL , [ BX ] MOV DS , [ BX+SI ]

③reg/mem ← segreg 通用寄存器 /存储器 ← 段寄存器 MOV BX , CS MOV [ BX ] , DS

④reg/mem ← data 通用寄存器 /存储器 ←立即数 MOV Al , 9 MOV BX , OFFSET buffer MOV [ value ] , 0 MOV WORD PTR [ BX ] , 1

Page 91: 第三章  80x86 的指令系统

91

MOV 指令特点及注意事项 :

双操作数指令 ( 注意双操作指令的特点)

可进行字节或字传送 不允许存储器传送到存储器

MOV [ BX ] , value

MOV [DI] , [SI]

MOV AX , value

MOV [ BX ] , AX

MOV AL , [SI]

MOV [ DI ] , AL

Page 92: 第三章  80x86 的指令系统

92

可对 DS 、 ES 、 SS 赋值 但不允许立即数直接传送给段寄存器

MOV DS , AX

MOV ES , [BX]

MOV DS , 1000H

MOV AX , 1000H

MOV DS , AX

CS 不能做目的操作数 , 不能通过传送指令改变 CS 的值

MOV CS , AX

Page 93: 第三章  80x86 的指令系统

93

不允许段寄存器传送到段寄存器

MOV ES , DS

MOV AX , DS MOV ES , AX

D:\MASM>DEBUG-A1693:0100 MOV ES, DS ^ Error1693:0100 MOV AX, DS1693:0102 MOV ES, AX1693:0104-

Page 94: 第三章  80x86 的指令系统

94

2) PUSH入栈操作

格式 PUSH src

执行 ( SP) ← ( SP) - 2

( SS : SP) ← ( src)

特点 :

单操作数指令 操作数为 16 位,可以是 reg/segreg/mem, 不可以是 data

reg : AX, BX, CX, DX, SI, DI, BP, BX

segreg : CS, DS, ES, SS

mem : 字类型

SS:SP

SS:SP (src)

Page 95: 第三章  80x86 的指令系统

95

例: PUSH AX

若执行前: ( SS) = 2000H

( SP) = 1002H

( SS : SP) = 2010H

( AX) = 1234H

3B2A

10

高20

地址

SS:SP2000:1002

指令执行前(AX)=1234h

则执行后: ( SS) = 2000H

( SP) = 1000H

( SS : SP) = 1234H

( AX) = 1234H

1234

10

高20

地址SS:SP

2000:1000

指令执行后(AX)=1234h

不变 减 2 变不变

Page 96: 第三章  80x86 的指令系统

96

3) POP 出栈操作

特点 :

单操作数指令操作数为 16 位,可以是 reg/segreg/mem, 不可以是 data

reg : AX, BX, CX, DX, SI, DI, BP, BX

segreg : DS, ES, SS, 不允许是 CS

mem : 字类型

SS:SP

SS:SP (dst)

格式 POP dst

执行 ( dst) ← ( SS : SP)

( SP) ←( SP) + 2

Page 97: 第三章  80x86 的指令系统

97

若执行前: ( SS) = 2000H

( SP) = 1000H

( SS : SP) = 1234H

( BX) = 5678H

1234

10

高20

SS:SP2000:1000

指令执行前

地址

(BX)=5678h

例: POP BX

1234

10

高20

SS:SP2000:1002

指令执行后

地址

(BX)=1234h

则执行后: ( SS) = 2000H

( SP) = 1002H

( SS : SP) = 2010H

( BX) = 1234H

不变 加 2

变 变

Page 98: 第三章  80x86 的指令系统

98

例:执行下列程序段 PUSH AX ①

PUSH BX ② MOV AX , 66H ③ MOV BX , 99H ④ POP BX ⑤ POP AX ⑥

若执行前( SS) = 3000H( SP) = 200EH( SS:SP) = 1234H( AX) = 0A0BH( BX) = 0C0DH

3000:200ESS:SP 执行前

(AX)=0A0B (BX)=0C0D

3412

执行①后 3000:200C

SS:S

P 0B0A

3000:200A

SS:S

P 执行②后 0D0C0B0A

3000:200CSS:SP

执行⑤后 : (BX)=0C0D0D0C0B0A

执行 ③④后 (AX)=0066 (BX)=0099执行 ③④后 (AX)=0066 (BX)=0099

3000:200A

SS:S

P 执行②后 0D0C0B0A 执行⑥后 : (AX)=0A0B

3000:200ESS:SP

(BX)=0C0D

执行 ③④后 (AX)=0066 (BX)=0099

0D0C0B0A

Page 99: 第三章  80x86 的指令系统

99

用 PUSH往 SS 段传送一批数据后,再用 POP取出时,取出单元的顺序与存放时的顺序正好相反,“后进先出”

⑥ POP AX (AX)=0A0B①PUSH AX

3000:200E

SS:S

P 执行前

3000:200CSS:SP

3000:200ASS:SP ②PUSH BX

3000:200ESS:SP

3000:200CSS:SP

0D0C0B0A3412

⑤ POP BX (BX)=0C0D

(AX)=0A0B (BX)=0C0D

④MOV AX,0066 (BX)=0099

③MOV AX,0066 (AX)=0066

Page 100: 第三章  80x86 的指令系统

100

堆栈是一个内存区域。 通常用于存放一些重要数据 ,

如程序的地址、或是需要恢复的数据。 SS:SP

为方便数据的存放和恢复, 设置专门的指针,指向堆栈中要操作的单元。 段值由 SS 给出,偏移地址由 SP 给出

SS → 堆栈段寄存器 (stack segment)

SP → 堆栈指针寄存器 (stack point)

堆栈的概念 stack

Page 101: 第三章  80x86 的指令系统

101

堆栈操作指令 PUSH 和 POP , 对 SS 和 SP 指向的内存单元, 以“后进先出”方式进行操作。

PUSH → 入栈操作 SP 减小 POP → 出栈操作 SP增加

SP 指向栈顶,即堆栈的顶部,

编程员通过设置堆栈区域, 利用堆栈操作,可方便的进行数据的存放和恢复。

SS:SP

SS:0000

SS:FFFF

堆栈未用空间

Page 102: 第三章  80x86 的指令系统

102

堆栈使用的场合

用堆栈保存恢复信息 ( 如上例)

子程序的调用、返回以及中断调用、返回 (控制转移指令中介绍)

用堆栈传送数据 (程序设计中介绍)

Page 103: 第三章  80x86 的指令系统

103

注意事项

堆栈是一重要数据结构,使用堆栈应有明确目的。

不乱用堆栈操作,不乱修改堆栈内容。

PUSH 、 POP 、 PUSHF 、 POPF 、

CALL 、 RET 、 INT 、 IRET

乱修改 SS 和 SP 的内容

包括 乱用 BP参与的存储器操作数

乱用指令

Page 104: 第三章  80x86 的指令系统

104

PUSH 和 POP 指令只能对字操作。

PUSH AL

POP BYTE PTR [BX]

可以对段寄存器操作 但 POP 不能对 CS 操作

PUSH DS

PUSH CS

POP ES

POP CS

Page 105: 第三章  80x86 的指令系统

105

4 ) XCHG 交换指令

格式 XCHG oprd1 , oprd2

执行 (oprd1) (oprd2)

reg reg

reg mem

mem reg

可实现

Page 106: 第三章  80x86 的指令系统

106

例 XCHG AX, BX 字操作

执行前( AX ) = 1122H ( BX ) = 3344H

执行后( AX ) = 3344H ( BX ) = 1122H

例 XCHG AH, BL 字节操作

执行前( AX ) = 1122H ( BX ) = 3344H

执行后( AX ) = 4422H ( BX ) = 3311H

Page 107: 第三章  80x86 的指令系统

107

XCHG oprd1 , oprd2

注意事项 :

双操作数指令

可进行字或字节操作

不允许对立即数、段寄存器做操作数

XCHG AX, 4

XCHG BX, DS

Page 108: 第三章  80x86 的指令系统

108

2. 地址传送指令 LEA 、 LDS 、 LES

LEA 有效地址传送

格式 LEA reg, mem

执行 ( reg ) ← mem 的 EA

即 寄存器 ← 存储器操作数的偏移地址

Page 109: 第三章  80x86 的指令系统

109

执行后 ( BX ) = 1000H

注意:

OFFSET 是汇编程序提供的一个操作符,不是 CPU 的指令

LEA BX, buffer

例 buffer 是一个符号地址表示的内存操作数 ( 变量 ) 。

…...12h34h56h…...

buffer

内存

DS: 1000h若变量 buffer 的偏移地址 = 1000H

等价于  MOV BX , OFFSET buffer

Page 110: 第三章  80x86 的指令系统

110

buffer 1A

2B

3C

4D

、、、

、、、

例 将 buffer 为首的 4 个字节内存内容相加,存放在 AL 中。

MOV AX, SEG buffer MOV DS, AX

LEA BX, buffer MOV CX, 4 MOV AL, 0

exit: ADD AL, [BX] INC BX DEC CX ;(cx) =(cx) -1 JNZ exit ;ZF ≠ 0, 转至 exit

说明: 1) 操作符 SEG 的作用是取变量的段地址。 执行完前两条指令后, (DS)=buffer 的段值 2) 操作符 OFFSET 的作用是取变量的偏移地址

执行完 LEA  BX, buffer, (BX) 为 buffer 的偏移地址,

3) 操作数 [BX] 是以 DS 为段值, BX 为偏移值的内存单元

Page 111: 第三章  80x86 的指令系统

111

LEA reg, mem

特点及注意事项:

目的操作数 reg 应是 16 位通用寄存器 LEA ES, [BX]

LEA AL, buffer

LEA 6, [BX+SI]

LEA [DI], buffer

源操作数应是存储器操作数 LEA BX, AX

传送的是内存单元的有效地址,与其内容无关。

…...12h34h56h…...

buffer

内存

Page 112: 第三章  80x86 的指令系统

112

3. 标志传送 PUSHF 、 POPF 、 LAHF 、 SAHF

SS:SP

SS:SP (PSW)

2) POPF 标志出栈格式 POPF

执行 ( PSW)← ( SS : SP) ( SP) ← ( SP) + 2

SS:SP

SS:SP (PSW)

1) PUSHF 标志入栈格式 PUSHF

执行 ( SP ) ← ( SP) - 2 ( SS : SP) ← ( PSW)

Page 113: 第三章  80x86 的指令系统

113

特点及注意事项:

无操作数的形式,操作数隐含为 ( PSW)

PUSHF AX

POPF CX

PUSHF 和 POPF 用于标志信息的保存和恢复

Page 114: 第三章  80x86 的指令系统

114

二 . 算术运算指令

二进制运算 十进制调整

加 ADD, ADC, INC AAA, DAA

减 SUB, SBB, DEC, NEG, CMP AAS, DAS

乘 MUL, IMUL AAM

除 DIV, IDIV AAD

符号扩展指令: CBW、CWD

指令分类:

Page 115: 第三章  80x86 的指令系统

115

特点: 带符号数用补码表示 如 MOV AX, -1 等价于 MOV AX, 0FFFFh

对加、减运算,不区分无符号数、带符号数 对乘、除运算,区分无符号数、带符号数 可进行字节或字操作 影响状态标志 十进制运算方法

当数据用压缩或非压缩 BCD码表示时,为使运算的结果仍为 BCD码表示,需对结果进行调整。 十进制运算 = 二进制运算 + 十进制调整

Page 116: 第三章  80x86 的指令系统

116

十进制数码 0 1 2 3 4

8421 BCD码 0000 0001 0010 0011 0100

十进制数码 5 6 7 8 9

8421 BCD码 0101 0110 0111 1000 1001

BCD码( Binary Coded Decimal )

用二进制编码表示十进制数。 常用 8421 BCD码 , 与十进制数码对应关系:

例 48 的 BCD码为 ( 0100 1000 ) BCD

Page 117: 第三章  80x86 的指令系统

117

根据在内存的存放形式,分压缩 BCD码和非压缩 BCD码1) 压缩 BCD码 一字节存放 2 个 BCD码。

如 2148 的压缩 BCD码为:( 0010 0001 0100 1000 ) 压缩 BCD

在内存中占 2 字节

2) 非压缩 BCD码一字节存放 1 个 BCD码。 如 2148 的非压缩 BCD码为:

( 00000010 00000001 00000100 00001000 ) 非压缩 BCD

在内存中占 4 字节

Page 118: 第三章  80x86 的指令系统

118

当数据用压缩或非压缩 BCD码表示时,为使运算的结果仍为 BCD码表示,需对结果进行调整。 十进制运算 = 二进制运算 + 十进制调整

例  (0000 1000 ) 压缩 BCD + (0000 1001) 压缩 BCD

= (0001 0111 ) 压缩 BCD

计算机计算过程 看作压缩 BCD

0000 1000 08 + 0000 1001 09 0001 0001 11

二进制运算

十进制调整 + 0000 0110 0001 0111 17

Page 119: 第三章  80x86 的指令系统

119

1. 加法运算指令

指令格式 执 行 操 作

ADD dst, src (dst) ← (dst) + (src)

ADC dst, src (dst) ← (dst) + (src) + CF

INC oprd (oprd) ← (oprd) + 1

ADD 、 ADC 为双操作数指令 INC 为单操作数指令 除 INC 指令不影响 CF 外, 6 个状态标志均据结果设置

ADC带进位加法,实现字以上运算

OF DF IF TF SF ZF AF PF CF

Page 120: 第三章  80x86 的指令系统

120

CFA1H 1100 1111 1010 0001 + 62A0H + 0110 0010 1010 0000 111 1 1 1 1111 1 3241H 0011 0010 0100 0001

例 1 编程完成 CFA1H + 62A0H

MOV DX , 0CFA1HADD DX , 62A0H

执行后 :( DX) =3241H CF=1 , OF=0 , SF=0 , ZF=0

(注意 CF 和 OF 的判断方法 )

Page 121: 第三章  80x86 的指令系统

121

三组指令执行后的结果均为:(AL)=0FDH, CF=0, OF=0, SF=1, ZF=0

MOV AL, 0F1H

ADD AL, 0CH

MOV AL, 241

ADD AL, 12

MOV AL, -15

ADD AL, 12

F1 H+ 0C H FD H

二进制运 算

241+ 12 253

看 作无符号数

(-15)+ 12 (-3)

看 作带符号数

B0

F1

04

0C

、、、

、、、

第一条指 令

第二条指 令

三组机器码相同:

对加、减运算, CPU 计算时不区分无符号数、带符号数

Page 122: 第三章  80x86 的指令系统

122

例 2 INC AL

  执行前 ( AL) = FFH

执行后 :

( AL) =00H

CF= 不变, OF=0 , ZF=1 , SF=0

FFH + 01H 11 00H

Page 123: 第三章  80x86 的指令系统

123

01FFH+ 0001H 11 0200H

例 3 value 是一个字变量   OFFSET value = 1000H

 ( DS) =2000H ,( 21000H) =01FFH

value FF21000H 01

执行前

value 0021000H 02

执行后执行后:  ( 21000H) =0200H

CF= 不变, OF=0 , ZF=0 , SF=0

注意是内存单元内容加 1 ,而非地址加1

INC value

或写成 :

INC [value]

Page 124: 第三章  80x86 的指令系统

124

例 4 将 buffer 为首的 4 个字节内存内容相加,存放在 AL 中。

buffer 1AB7C5D6

若编程如下 ,MOV CX, 4MOV AL, 0

exit: ADD AL, [buffer] INC buffer DEC CX

JNZ exit 

不能实现 , 为什么?

…... MOV CX, 4 LEA BX, buffer

MOV AL, 0exit: ADD AL, [BX]

INC BX DEC CX JNZ exit

实现的是 1A+1B+1C+1D指令 INC buffer 将 buffer 指向的内容加 1 ,而不是地址 buffer 加 1

Page 125: 第三章  80x86 的指令系统

125

例 5 两双字相加 0002F365H + 0005 E024 H = ?

MOV AX , 0F365H ①ADD AX , 0E024H ②MOV BX , 0002H ③ADC BX , 0005H ④

0002 F365 H + 0005 E024 H   1    0008 D389 H

结果存放在 : 0008 D389( BX) ( AX)

执行完①、②: (AX)= D389H CF=1, OF=0, SF=1, ZF=0 执行完③、④: (BX)= 0008H CF=0, OF=0, SF=0, ZF=0

分析: 8086/8088 只能按字节或字相加。 位数在字以上的操作数,先加低位,再加高位, 加高位时加入从低位产生的进位。

Page 126: 第三章  80x86 的指令系统

126

指令格式 执行操作 SUB dst, src (dst) ← (dst) - (src)

SBB dst, src (dst) ← (dst) - (src) - CF

DEC oprd (oprd) ← (oprd) - 1

NEG oprd (oprd) ← 0 - (oprd)

CMP oprd1, oprd2 (oprd1) - (oprd2)

2. 减法运算指令

SUB 、 SBB 、 CMP 为双操作数, DEC 、 NEG 为单操作数 SBB 为带进位减法 除 DEC 不影响 CF 标志外, 6 个状态标志均据结果置位 NEG求补运算,等价于用 0 减去操作数。

其对标志位的影响,由 0 减去该操作数的过程决定。

Page 127: 第三章  80x86 的指令系统

127

例 1 编程完成 2D04H – 3AB0H

执行后 : ( AX) =0F254H CF=1 , OF=0 , SF=1 , ZF=0

2D04H 0010 1101 0000 0100 - 3AB0H - 0011 1010 1011 0000 1 1 1111 1 1 111 F254H 1111 0010 0101 0100

MOV AX , 2D04HSUB AX , 3AB0H

借位

Page 128: 第三章  80x86 的指令系统

128

例 2 value 是一个字节变量

OFFSET value = 1000H

( DS ) =2000H ,( 21000H ) =00H

DEC value

执行后:( 21000H ) =0FFH

CF= 不变, OF=0 , ZF=0 , SF=1

注意是内存单元内容减 1 ,而非地址减 1

00 H - 01 H 11 FFH

Page 129: 第三章  80x86 的指令系统

129

例 3 MOV AH, 80H

NEG AH

00 H 0000 0000 B - 80 H - 1000 0000 B 1 1 80H 1000 0000B

执行后: ( AL) =80H CF=1 , OF=1 , ZF=0 , SF=1

Page 130: 第三章  80x86 的指令系统

130

例 4 用指令完成两双字相减运算

0546 7A70H - F001 A543H

MOV AX , 7A70H

SUB AX , A543H

MOV BX , 0546H

SBB BX , 0F001H

Page 131: 第三章  80x86 的指令系统

131

CMP oprd1, oprd2 ; (oprd1) - (oprd2)

① 据 ZF判断两数是否相等CMP A, B

ZF=1 两数相等 , A = B ;ZF=0 两数不等 , A ≠ B

② 据 ZF 和 CF 判断两无符号数关系 CF= 1 A低于 B

CF= 0 A高于等于 B

CF=1 或 ZF=1 A低于等于 B

CF=0 且 ZF=0 A高于 B

利用 CMP 执行后的标志值,比较两操作数之间的关系

比较指令 CMP ,进行两操作数相减操作, 但只影响标志值,不影响操作数 ( 减的结果不保存 )

Page 132: 第三章  80x86 的指令系统

132

条件转移指令 判断条件

低于 JB next CF = 1

低于等于 JBE next CF = 1 或 ZF = 1

高于 JA next CF = 0 且 ZF = 0

高于等于 JAE next CF = 0

CMP AX, BX ; 比较 JAE above ;高于等于则跳转 XCHG AX, BX ;低于则交换

above: 、、、

例 将 AX 和 BX 中较大的无符号数,存于AX 中

Page 133: 第三章  80x86 的指令系统

133

CMP A , B

③ 用 ZF 、 SF 和 OF判断两带符号数关系 OF=0 ,不溢出情况,

SF=0 , A≥B SF=1 , A< B

OF=0, SF=0 A≥B

OF=0, SF=1 A< B

OF=1, SF=1 A> B

OF=1, SF=0 A< B

0 - 1 正 - 负 = 负,结果 SF = 1, OF=1

1 但,正 > 负,知 A > B 1 - 0 负 - 正 = 正,结果 SF = 0, OF=1 0 但,负 < 正,知 A < B

OF=1 ,溢出情况,( 由符号位可决定是否溢出 )

Page 134: 第三章  80x86 的指令系统

134

结合 ZF, 得到结论 :

SF OF

00

01

10

11

SF∨ OF 0 1 1 1

或运算:有 1则 1,全 0则 0

逻辑运算:

CMP A, B 两数关系

SF ∨ OF = 0 A≥ B

SF ∨ OF = 1 A<B

(SF ∨ OF) ∨ ZF =0 A>B

(SF ∨ OF) ∨ ZF=1 A≤ B

思考:可否只用 ZF 和 SF判断两符号数关系?

SFOF

00

01

10

11

SF∨ OF 0 1 1 0

异或运算: 异则 1,同则 0

Page 135: 第三章  80x86 的指令系统

135

条件转移指令 判断条件

小于 JL next SF ∨ OF = 1

小于等于 JLE next (SF ∨ OF)∨ ZF=1

大于 JG next (SF ∨ OF)∨ ZF =0

大于等于 JGE next SF ∨ OF=0

例 将 AX 和 BX 中较大的带符号数,存于 AX 中

CMP AX, BX ; 比较 JGE great ;大于等于则跳转 XCHG AX, BX ; 小于则交换

great: 、、、

Page 136: 第三章  80x86 的指令系统

136

3. 乘法指令

指令格式 执行操作

MUL src

若 src为字节类型: (AX) ← (AL)× (src) 若 src为字类型: (DX),(AX) ← (AX)× (src)

将被乘数、乘数看作无符号数,进行乘运算 乘的结果也为无带符号数

IMUL src 执行的操作与MUL相似 将被乘数、乘数看作带符号数, 进行乘运算 乘的结果也为带符号数

无符号数乘法

带符号数乘法

Page 137: 第三章  80x86 的指令系统

137

MUL src

IMUL src

单操作数指令 源操作数 ( 乘数 ) 类型决定操作类型 目的操作数 ( 被乘数 ) 隐含。 字节乘 AL 字乘 AX

字节相乘的结果存放在 AX 中 字相乘的结果存放在 DX 、 AX 中 MUL 用于无符号数运算 IMUL 用于带符号数运算

Page 138: 第三章  80x86 的指令系统

138

影响 CF 和 OF ,对其他条件码无定义(不确定)

指令 MUL

字节相乘, AH=0 , CF=OF=0 ,否则 CF=OF=1

字相乘, DX=0 , CF=OF=0 ,否则 CF=OF=1

对指令 IMUL

字节相乘, AH=0 或 AH=FFH , CF=OF=0 ,否则 CF=OF=1

字相乘, DX=0 或 DX=FFFFH , CF=OF=0 ,否则 CF=OF=1

Page 139: 第三章  80x86 的指令系统

139

例 (AL) = 0B4H , (BL) = 11H

指令中源操作数为字节类型,故是字节操作

① MUL BL ② IMUL BL

看作无符号数 (AL) = 180D

(BL) = 17D

180×17 = 3060D

= 0BF4H

执行 MUL BL 后: (AX) = 0BF4H

看作带符号数(AL) = -76D

(BL) =17D

(-76)×17 = -1292D

= 0FAF4H

执行 IMUL BL 后:(AX) = 0FAF4H

Page 140: 第三章  80x86 的指令系统

140

例 (AX)=0FFFFH , (BX)=0FFFFH

指令中源操作数为字类型,故是字操作

① MUL BX

执行 MUL BX 后: (DX) = 0FFFEH

(AX) = 0001H

看作无符号数 (AX )= (BX) = 65535

65535×65535

= 4294836225

= 0FFFE 0001H

② IMUL BX

看作带符号数 (AX)= (BX)=-1

(-1)×(-1)

= 1

= 0000 0001H

执 行 IMUL BX 后:

(DX) = 0000H

(AX) = 0001H

Page 141: 第三章  80x86 的指令系统

141

4. 除法指令

指令格式 执行操作

DIV src

无符号数除法

(src)为字节类型:

(AL) ← (AX) / (src) 的商

(AH) ← (AX) / (src) 的余数

(src)为字类型:

(AX) ← DX) , (AX) / (src) 的商

(DX) ← (DX) , (AX) / (src) 的余数

将被除数、除数看作无符号数,进行除法运算,

商、余数也为无符号数

IDIV src

带符号数除法

执行的操作与 DIV相同,

将被除数、除数看作带符号数,进行除法运算

商、余数也为带符号数,余数的符号与被除数同

Page 142: 第三章  80x86 的指令系统

142

单操作数指令 源操作数 ( 除数 ) 类型 决定指令操作类型 目的操作数 (被除数 )隐含 字节操作在 AX 中;字操作在 DX, AX 中 除的结果,字节操作在 AX 中;字操作在 DX, AX中 除法指令对所有条件码位均无定义 下列情况自动转入 0 中断处理: (1) 除数为 0

(2) 字节操作,商的范围超出字节范围 字操作时,商的范围超出字范围

Page 143: 第三章  80x86 的指令系统

143

除法指令举例

例 (AX)=0501H , (BL)=0C6H

(1) DIV BL (2) IDIV BL

看作无符号数 看作带符号数 (AL) = 1281D (AL) = 1281D

(BL) = 198D (BL) = -58D

1281/198商 = 6D 1281/ (-58)商 = -22D=0EAH

余数 =93D=5DH 余数 =5D

执行 DIV BL后: 执行 IDIV BL后: (AX) = 5D06H (AX) = 05EAH

Page 144: 第三章  80x86 的指令系统

144

5. 符号扩展指令

指令格式 执行操作

CBW

将 (AL) 的符号扩展到 AH中

(AL)的 D7=0,(AH)=00H

D7=1,(AH)=FFH

CWD

将 (AX) 的符号扩展到 DX中

(AX)的 D15=0,(DX)=0000H

D15=1,(DX)=FFFFH

Page 145: 第三章  80x86 的指令系统

145

无操作数格式 操作数隐含

字节操作,源在 AL ,目的在 AX字 操 作,源在 AX ,目的在 DX,AX

对条件码无影响 符号扩展指令应对带符号数操作 扩展后,表示的数值大小不变,只是位数发生变化 8 位 16 位 16 位 32 位 应用场合: 除法指令中,使被除数满足要求。

字节操作,被除数为 16 位字操作,被除数为 32 位

加减运算中,使两操作数类型一致如:字与字节相加、减时

如:双字与字之间的相加、减时

Page 146: 第三章  80x86 的指令系统

146

符号扩展指令举例例 CBW 执行前 (AL)=01H , (AH)=0FFH 执行后 (AL)=01H , (AH)=00H

例 CWD 执行前 (AX)=0FF00H , (DX)=0011H 执行后 (AX)=0FF00H , (DX)=0FFFFH

例 ( AL ) =0FFH ,将其内容扩展至 (AX) 中 看作无符号数为 255 , 若用 MOV AH , 0H (AX)=00FFH=255D 若用 CBW (AX)=0FFFFH=65535≠原数 故,对无符号数的扩展不能用符号扩展指令 对无符号数的扩展,直接给高位赋 0 。

Page 147: 第三章  80x86 的指令系统

147

BCD 码运算的十进制调整指令 专用于对 BCD 码运算的结果进行调整 包括: AAA 、 DAA 、 AAS 、 DAS 、 AAM 、

AAD 均为隐含寻址,隐含的操作数为 AL 和 AH 为何要对 BCD 码的运算结果进行调整?

BCD码本质上是十进制数,即应遵循逢十进一的规则。而计算机是按二进制(十六进制)进行运算,并未按十进制规则进行运算。

Page 148: 第三章  80x86 的指令系统

148

8088 的调整指令主要用于十进制数的调整。这些指令包括:

   AAA :对 AL 中非压缩 BCD 码求和的结果进行调整。

   AAS :对 AL 中非压缩 BCD 码求差的结果进行调整。

  AAD :在实现十进制除法时,在除法指令前对 AX 用中非压缩 BCD 码表示的十进制数进行调整。

   AAM :在实现十进制乘法时,对 AX 中两个非压缩 BCD码相乘的结果进行调整。

  DAA :对 AL 中的两个压缩 BCD 码相加之和进行调整,得到用压缩 BCD 码表示的十进制和。

  DAS :对 AL 中的两个压缩 BCD 码相减之差进行调整,得到用压缩 BCD 码表示的十进制差。

148

Page 149: 第三章  80x86 的指令系统

149

加法的十进制调整指令

非压缩 BCD 码加法调整 AAA本指令对在 AL 中的由两个未组合的 BCD码相加后的结果进行调正,得到一个正确的未组合的 BCD 码。AAA 指令只影响 AF 和 CF ,其余标志无定义。AAA 指令应紧跟在 ADD 或 ADC 指令之后。

149

Page 150: 第三章  80x86 的指令系统

150

AAA 指令的操作如下:

150

如果 AL 的低 4 位> 9∨AF=1 ,则: ① AL←(AL)+6,(AH)←(AH)+1,AF←1 ② AL←((AL)∧0FH) ③ CF←AF否则 AL←(AL)∧0FH

Page 151: 第三章  80x86 的指令系统

151

调整原理:先看一个例子 计算 8 + 9 0000 1000 见右式 +0000 1001 0001 0001 = 11

结果应为 17 ,而计算机相加为 11 ,原因在于运算过程中,如遇到低 4 位往高 4 位产生进位时(此时 AF=1 )是按逢十六进一的规则,但 BCD 码要求逢十进一,因此只要产生进位,个位就会少 6 ,这就要进行加 6 调正。

151

这个 1代表了 16 ,而实际上仅应为 10 ,即多进了 6 。

Page 152: 第三章  80x86 的指令系统

152

实际上当低 4 位的结果> 9( 即 A ~ F 之间 )时,也应进行加 6 调正 ( 原因是逢十没有进位,故用加 6 的方法强行产生进位 ) 。如对上例的结果进行加 6 : 0001 0001 11 + 0000 0110 6 0001 0111 17 ^ 0000 1111---------------------- 1 0000 0111

152

Page 153: 第三章  80x86 的指令系统

153

压缩 BCD 码加法调整 DAA 两个压缩 BCD 码相加结果在 AL 中,通过

DAA 调整得到一个正确的压缩 BCD 码 . 指令操作 ( 调整方法 ) : 若 AL 的低 4 位> 9∨AF=1 则 (AL)←(AL)+6 , AF←1 若 AL 的高 4 位> 9∨CF=1 则 (AL)←(AL)+60H , CF←1 除 OF 外, DAA 指令影响所有其它标志。 DAA 指令应紧跟在 ADD 或 ADC 指令之后。

153

Page 154: 第三章  80x86 的指令系统

154

例: 0100 1000 48H MOV AL , 48H + 0111 0100 74H MOV BL , 74H 1011 1100 BCH ADD AL , BL + 0110 0110 66H DAA 1 0010 0010 1 22H

( 进位 ) ( 进位 ) 执行 ADD 后, (AL)=BCH ,高 4 位低 4 位均大于 9 ,故DAA 指令执行加 66H 调整,最后结果为: (AL)=22H, CF=1, AF=1

154

Page 155: 第三章  80x86 的指令系统

155155

3) 乘法的十进制调正指令 AAM

对 AX 中由两个非压缩 BCD 码相乘的结果进行调整。调整操作为: (AL)/0AH, (AH)← 商, (AL)← 余数

隐含的操作寄存器为 AL 和 AH ;AAM 跟在 MUL 指令之后使用;影响标志位 PF 、 SF 、 ZF ,其它无定义 ;用 AAM 可实现≤ 99 的二 - 十进制转换。

Page 156: 第三章  80x86 的指令系统

156156

例 1 :按十进制乘法计算 7×8=? 程序段如下:

MOV AL,07H ; (AL)=07HMOV CL,08H ; (CL)=08HMUL CL ; (AX)=0038HAAM ; (AH)=05H,(AL)=06H

所得结果为非压缩的 BCD 码。例 2 :把 3AH 转换成等值的十进制数。 MOV AL , 3AH ; 58 AAM ; (AH)=05H , (AL)=08H

Page 157: 第三章  80x86 的指令系统

157157

4) 除法的十进制调正指令 AAD

对非压缩 BCD 除法运算进行调整。调整操作为: (AL)←(AH)×0AH + (AL) AH ← 0

隐含的操作寄存器为 AH , AL ;AAD 要在 DIV 指令之前使用;影响标志位 PF 、 SF 、 ZF ,其它无定义 ;用 AAD 可实现≤ 99 的十 - 二进制转换。

Page 158: 第三章  80x86 的指令系统

158158

例 1 :按十进制除法计算 55÷7=?

程序段如下:MOV AX, 0505H ; (AX)=55BCD

MOV CL, 07H ; (CL)= 7

AAD ; (AX)=0037H

DIV CL ; (AH)=6, (AL)=7

所得结果为非压缩的 BCD 码(商 7 余 6 )。

例 2 :把 73 转换成等值的二进制数。 MOV AX, 0703H ; (AX)= 73BCD

AAD ; (AX)= 0049H

Page 159: 第三章  80x86 的指令系统

159

请继续学习 8086系列指令系统…