第三章 80x86 的指令系统
-
Upload
farsiris-hormuzd -
Category
Documents
-
view
85 -
download
6
description
Transcript of 第三章 80x86 的指令系统
1
第三章 80x86 的指令系统
指令系统的特点及指令的基本格式
§3.1 80x86 寻址方式
§3.2 80x86 指令系统
2
一、概述 1. 程序语言简介 2. 8086/8088 指令简介
指令系统的特点及指令的基本格式
3
一、概述
1. 程序语言简介
2. 8086/8088 指令简介
4
1. 程序语言简介
1) 指令、指令系统和程序
2) 机器码和机器语言
3) 助记符和汇编语言
4) 高级语言
5
1) 指令、指令系统和程序
CPU 是一个可以完成一些基本操作的电子器件。
用编码表示 CPU 的一个基本操作,称为一条指令。
全部指令集称为指令系统。 指令系统反映 CPU 的基本功能,
是硬件设计人员和程序员能见到的机器的主要属性,
是硬件构成的计算机系统向外部世界提供的直接界面。
6
一个 CPU 的指令系统是固定的,
不同类型的 CPU 其指令系统不同 ;
同一系列向上兼容。
程序是为要解决的问题编写出来的指令集合。
用户为解决自己的问题所编写的程序称为源程序。
7
2) 机器码和机器语言
用二进制数编码表示的指令,称为机器指令或机器码。
机器语言是机器码及其使用的一组规则。
用机器语言编写的程序称为目标程序。
机器语言特点: CPU 能直接识别的唯一语言 面向机器,可直接被计算机执行 执行速度快,占用内存空间小 编程效率低、可读性差、可移值性差
应用:显示设备简单的单片机、家用电器、固化在 ROM 上的程序等
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
9
3) 助记符和汇编语言
助记符是有助记忆、并能描述指令功能的符号。 通常是指令功能的英文单词的缩写。
例 数的传送指令用助记符 MOV 加法用 ADD ,转移用 JMP 等
用助记符等表示的指令称为汇编格式指令例 MOV AL, 0
汇编语言是汇编格式指令、伪指令及其使用的一组规则。
用汇编语言编写的程序称汇编语言程序。
10
上例 将地址为 2000H 和 2001H 的两内存单元内容相加, 结果存在地址 2002H 单元中。
汇编格式指令与机器指令一一对应
用汇编语言编好的程序,
必须翻译成机器码表示的程序,计算机才能运行。
汇编程序是将汇编语言程序翻译成机器语言的一种系统程序。
用机器码编程: A0 00 20 02 06 01 20 A2 02 20
用汇编语言编写的确程序段为:MOV AL , var1ADD AL , var2MOV var3 , AL
11
汇编语言和机器语言编写的程序:面向机器,反映机器运行的实际过程 ,
与计算机的硬件结构和指令系统密切相关算法是用计算机的指令 , 寄存器等描述,
要了解 CPU 的编程结构、寻址方式、指令系统才能设计程序占内存少,执行速度快编写繁琐、调试困难
相对于机器语言编写的程序:
汇编语言程序,易读易懂,便于修改。
12
3) 高级语言
高级语言是独立于机器、面向过程或对象的语言。
算法是按照人的思维方式给出,比较接近人的自然语言。
上例 高级语言程序段为:
var3 = var1 + var2
由编译程序将高级语言源程序翻译目标程序,
即用机器码表示的程序,机器才能执行。(不同类型机器由于指令系统不同,它们的编译程序不同 )
Fortran、 Basic、 C 等均是高级语言。 使用高级语言编程,效率高,可读性、可移植性强。
13
2. 8086/8088 指令简介
指令格式
1) 操作码
2) 操作数
(1) 来源 (2) 个数 (3) 类型 (4) 执行速度
14
指令格式 操作码 操作数 例 ADD AL , 10H
数据传送算术运算逻辑运算串操作控制转移处理机控制
按功能指令分六类
1) 操作码
指明 CPU 要执行什么样的操作。是一条指令必不可少的部分,用助记符表示。
15
2) 操作数
指明参与操作的数据或数据所在的地方。
了解操作数的来源、个数、类型、执行速度。
指令格式 操作码 操作数 例 ADD AL , 10H
16
(1) 操作数来源 指明操作数所在的地方
有三种来源:
① 操作数在指令中,称立即数操作数 如 MOV AL , 9
② 操作数在寄存器中,称寄存器操作数指令中给出用符号表示的寄存器名。 如 MOV AL , 9
③ 操作数在内存单元中,称存储器操作数或内存操作数 指令中给出该内存单元的地址。用 [ ]表示存储器操作数
如 MOV AL , [ 2000H ]
17
(2) 操作数个数
按指令格式中,操作数个数的多少分为三类:
无操作数 : 指令只有一个操作码,没有操作数
单操作数 : 指令中给出一个操作数
双操作数 : 指令中给出两个操作数。
18
① 无操作数: 指令只有一个操作码,没有操作数。
有两种可能:
▲ 有些操作不需要操作数。
如 HLT, NOP 等处理机控制指令。
▲ 操作数隐含在指令中。
如 STC , CLC 等处理机控制命令。
AAA , DAA 等调整指令。
19
② 单操作数 : 指令中给出一个操作数。
有两种可能:
▲有些操作只需要一个操作数
如 INC AL ; ( AL) ← ( AL) + 1
▲有些操作将另一个操作数隐含在指令中
如 MUL BL ; ( AX) ← ( AL)×(BL)
20
③ 双操作数 : 指令中给出两个操作数。
如 ADD AL , BL ; (AL) ← (AL) + (BL)
目的操作数 源操作数
操作后的结果通常存放在目的操作数中。
21
3) 操作数类型
指令应指明参与操作的数是字节还是字,即操作数的类型。
通常操作数的类型可由操作数本身隐含给出。
只在特殊情况下需要指明。
8086/8088:
有的操作既可对字节操作,又可对字操作
有的操作只允许对字操作
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
23
② 指令操作数中无寄存器,则由内存操作数的类型决定。
value 00H ….
内存
value 00H 00
H
例 value 是一个变量 ( 即内存操作数 );
若定义 value 为字节类型 :
则 MOV value , 0 是字节操作。
若定义 value 为字类型 :
则 MOV value , 0 是一个字操作。
24
例 MOV [ BX ], 0
③ 指令中无类型的依据,需对存储器操作数加类型说明。
用 PTR 属性伪操作说明类型。MOV byte PTR [BX] , 0 字节操作, [ BX ] ← 0MOV word PTR [BX] , 0
字操作, [ BX ] ← 0, [ BX+1 ] ← 0
25
4) 执行速度
寄存器操作数 立即数操作数 存储器操作数
例 mov AL , BL
mov AL , 0 mov AL , [ BX ]
哪条指令执行速度快?
三条指令:
操作类型相同,都是传送指令 ,且目的操作数相同,
不同的是源操作数。
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 ]
27
对同一类型指令,执行速度:
寄存器操作数 立即数操作数 存储器操作数
快 慢
例 mov AL , BL 快
mov AL , 0 mov AL , [ BX ] 慢
28
第一节、 8086/8088 的寻址方式
指明操作数的来源,即寻找(得到)操作数的方法。
共 7 种寻址方式:1. 立即数寻址2. 寄存器寻址3. 直接寻址4. 寄存器间接寻址 5 种与内存单元 5. 寄存器相对寻址 有关的寻址6. 基址加变址寄存器寻址 ( 存储器操作数 )
7. 相对基址加变址寄存器寻址
29
以数据传送指令 MOV 为例介绍寻址方式。
指令 MOV dst, src 执行 (dst ) ← ( src )
即: 源操作数的内容不变,
目的操作数 = 源操作数
30
一 . 立即数寻址
操作数在指令中,取来指令立即可得到操作数。
称该操作数为立即数。 立即数可以是 8 位或 16 位。
立即数常用来给寄存器或内存单元赋初值。
56B8
内存
20数作操
操作码
例 1 MOV AX , 2056H
结果 ( AH ) = 20H
( AL ) = 56H
例 2 MOV AL , 78 H
结果 ( AL ) = 78H
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
32
例 1 MOV AX , 2056H
执行后: (AX)=2056H
例 2 MOV BL , AH
执行前: (BL) = 12H, (AH) = 78H
执行后: (BL) = 78H (AH) = 78H
33
▲ 立即数寻址、寄存器寻址的操作数, 不用在取完指令后再到内存中取数。
DSESSSCS
IP
数据暂存器
PSW 标志寄存器 执行部件控制电路
指令译码器
AXBXCXDX
AHBHCHDH
SIDIBPSP
ALBLCLDL
寄存器组
指令队列
总线接口控制电路
运算器
地址加法器
、、、指令 1
指令 2
指令 3
指令 4
、、、数据 1
数据 2
数据 3
、、、
地址总线 AB
数据总线 DB
控制总线 CB
地
址
译
码
器
CPU 总线 内存
34
三 . 存储器寻址▲以下的 5 中寻址方式, 操作数存放在内存中,取完指令后,还需到内存取数。 指令中给出的是该操作数的地址,包括段地址和偏移地址。 DS
ESSSCS
IP
数据暂存器
PSW 标志寄存器 执行部件控制电路
指令译码器
AXBXCXDX
AHBHCHDH
SIDIBPSP
ALBLCLDL
寄存器组
指令队列
总线接口控制电路
运算器
地址加法器
、、、指令 1
指令 2
指令 3
指令 4
、、、数据 1
数据 2
数据 3
、、、
地址总线 AB
数据总线 DB
控制总线 CB
地
址
译
码
器
CPU 总线 内存
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 为偏移值的内存单元中
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
37
内存单元的地址由段地址和偏移地址构成
▲ 为减短指令长度 指令中只给出偏移地址的来源,段地址由默认关系给出。 MOV AL , [ 2000H ]
▲ CPU 根据偏移地址给出的方式, 按默认关系自动选择段寄存器,获取段值, 由段值、偏移值构成操作数所在内存单元的物理地址。
上例 PA= ( DS ) ×10H + 2000H
即选择 DS 寄存器的内容为段地址。
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 以上微处理器还有比例变址寻址基址比例变址寻址相对基址比例变址寻址
39
1 .直接寻址方式
存储器操作数的有效地址 EA 在指令中直接给出。
例 MOV AL, [ 1000H ]
默认段寄存器为 DS 。
操作数所在内存单元的物理地址为:
PA = ( DS )×10H + EA
40
直接寻址方式默认段寄存器为 DS
DSESSSCS
IP
数据暂存器
PSW 标志寄存器 执行部件控制电路
指令译码器
AXBXCXDX
AHBHCHDH
SIDIBPSP
ALBLCLDL
寄存器组
指令队列
总线接口控制电路
运算器
地址加法器
、、、指令 1
指令 2
指令 3
指令 4
、、、数据 1
数据 2
数据 3
、、、
地址总线 AB
数据总线 DB
控制总线 CB
地
址
译
码
器
CPU 总线 内存
41
例: MOV AX , [ 1000 H]
若 ( DS ) = 2000H
内存操作数的物理地址为:
PA = ( DS )×10H +EA
= 2000H × 10H + 1000H
= 21000H
执行后 (AX)= 3040H
21000 40
00A1
内存
10
30
指令
42
在汇编语言程序中,不直接用数值 表示偏移地址, 用符号代替数值表示地址,称符号地址 ( 变量名 ) 。
buffer 0A
0B
例 符号 buffer 表示一个地址。 MOV AX , [buffer]
或写成 MOV AX , buffer
源操作数为 buffer 指向的内存单元的内容
符号地址 ( 变量名 ) 经汇编连接后,与一个确定的数值地址相对应可用操作符 Offset 获取变量的偏移地址。
故 PA = ( DS )×10H + Offset buffer 指令执行结果 ( AX ) = 0B0A H
43
2. 寄存器间接寻址
存储器操作数的有效地址 EA 由寄存器给出 ,
寄存器的内容为操作数的有效地址。
可用的寄存器有 BX 、 SI 、 DI 、 BP
如 : MOV AL, [ BX ]
MOV AH, [ SI ]
MOV DL, [ DI ]
MOV DH, [ BP ]
44
默认段寄存器的关系:
①使用 BX 、 SI 、 DI ,默认段寄存器为 DS
(BX)
PA = ( DS )×10H + (SI)
(DI)
②使用 BP ,默认段寄存器为 SS
PA = ( SS )×10H + ( BP )
45
使用 BX 、 SI 、 DI 的寄存器寻址,默认段寄存器为 DS
DSESSSCS
IP
数据暂存器
PSW 标志寄存器 执行部件控制电路
指令译码器
AXBXCXDX
AHBHCHDH
SIDIBPSP
ALBLCLDL
寄存器组
指令队列
总线接口控制电路
运算器
地址加法器
、、、指令 1
指令 2
指令 3
指令 4
、、、数据 1
数据 2
数据 3
、、、
地址总线 AB
数据总线 DB
控制总线 CB
地
址
译
码
器
CPU 总线 内存
46
使用 BP 的寄存器寻址,默认段寄存器为 SS
DSESSSCS
IP
数据暂存器
PSW 标志寄存器 执行部件控制电路
指令译码器
AXBXCXDX
AHBHCHDH
SIDIBPSP
ALBLCLDL
寄存器组
指令队列
总线接口控制电路
运算器
地址加法器
、、、指令 1
指令 2
指令 3
指令 4
、、、数据 1
数据 2
数据 3
、、、
地址总线 AB
数据总线 DB
控制总线 CB
地
址
译
码
器
CPU 总线 内存
47
例: MOV AX , [ DI ]
若 ( DS ) = 3000H
( DI ) = 2000H
则内存操作数的物理地址为:
PA = ( DS )×10H + ( DI )
= 32000H
执行后 (AX) = (32000H) = 400BH
32000 0B
05
8B指 令
40
48
例: MOV AX , [ BP ]
若 ( SS ) = 4000H
( BP ) = 3000H
则内存操作数的物理地址为:
PA = ( SS )×10H + ( BP )
= 43000H
指令执行后 (AX) = (43000H) = 0102H
43000 02
46
8B指 令
01
49
3. 寄存器相对寻址
操作数的有效地址由一个寄存器与一个偏移量相加得到
偏移量(相对量)在指令中给出,范围在 0000 ~ FFFFH
可用的寄存器有 BX 、 DI 、 SI 、 BP , 与寄存器间接寻址相同
如 : MOV AL, [ BX +10H]
MOV AH, [ DI+20H ]
MOV DL, 30H [ SI ]
MOV DH, 40H [ BP ]
50
默认段寄存器的关系与寄存器间接寻址相同
①使用 BX 、 SI 、 DI ,默认段寄存器为 DS
(BX)
PA = ( DS )×10H + (SI) + 偏移量
(DI)
②使用 BP ,默认段寄存器为 SS
PA = ( SS )×10H + ( BP ) + 偏移量
51
例: MOV AX , [ BX+30H ]
若 ( DS ) = 2000H
( BX ) = 1000H
则内存操作数的物理地址为:
PA = ( DS )×10H + ( BX ) + 30H
= 21030H
指令执行后:
(AX) = (21030H) = 8976H
21030 76
30
47指 令
89
8B
52
例: MOV AX , 60H [ BP ]
若 ( SS ) = 3000H
( BP ) = 200H
则内存操作数的物理地址为:
PA = ( SS )×10H + ( BP ) + 60H
= 30260H
指令执行后:
(AX) = (30260H) = 0ABCH
30260 BC
60
46指 令
0A
8B
53
4. 基址加变址寻址
操作数的有效地址由 一个基址寄存器与一个变址寄存器之和给出。
可用的基址寄存器为 BX 、 BP
变址寄存器为 SI 、 DI
如 MOV AL , [ BX+SI ]
MOV AX , [ BX][DI ]
MOV DL , [ BP+SI ]
MOV DX , [ BP][DI ]
54
默认段寄存器由基址寄存器决定。
① 基址寄存器为 BX ,默认段寄存器为 DS
(SI)
PA = ( DS )×10H + ( BX ) +
(DI)
② 基址寄存器为 BP ,默认段寄存器为 SS
(SI)
PA = ( SS )×10H + ( BP ) +
(DI)
55
使用 BX 的基址加变址寻址,默认段寄存器为 DS
DSESSSCS
IP
数据暂存器
PSW 标志寄存器 执行部件控制电路
指令译码器
AXBXCXDX
AHBHCHDH
SIDIBPSP
ALBLCLDL
寄存器组
指令队列
总线接口控制电路
运算器
地址加法器
、、、指令 1
指令 2
指令 3
指令 4
、、、数据 1
数据 2
数据 3
、、、
地址总线 AB
数据总线 DB
控制总线 CB
地
址
译
码
器
CPU 总线 内存
56
使用 BP 的基址加变址寻址,默认段寄存器为 SS
DSESSSCS
IP
数据暂存器
PSW 标志寄存器 执行部件控制电路
指令译码器
AXBXCXDX
AHBHCHDH
SIDIBPSP
ALBLCLDL
寄存器组
指令队列
总线接口控制电路
运算器
地址加法器
、、、指令 1
指令 2
指令 3
指令 4
、、、数据 1
数据 2
数据 3
、、、
地址总线 AB
数据总线 DB
控制总线 CB
地
址
译
码
器
CPU 总线 内存
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
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 ]
59
默认段寄存器由基址寄存器决定 , 与基址加变址寻址相同
① 基址寄存器为 BX ,默认段寄存器为 DS
(SI)
PA = ( DS )×10H + ( BX ) + + 偏移量 (DI)
② 基址寄存器为 BP ,默认段寄存器为 SS
(SI)
PA = ( SS )×10H + ( BP ) + + 偏移量 (DI)
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
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
62
2. 段跨越前缀的使用
段跨越前缀
在指令中出现的指定内存单元段地址的段寄存器符号。
表示方法为 段寄存器名 :
例: MOV AX , ES : [ BX ]
ES : MOV AX , [ BX ] ( DEBUG 下格式)
为减小指令长度, CPU 采用默认关系获取段地址。
使用段跨越前缀可强行改变这种默认关系。
63
使用段跨越前缀的指令比不使用的指令要多占一个字节。
8B
07
指 令 MOV AX,ES:[BX]
26
指 令 MOV AX,[BX] 8B
07
64
使用段跨越前缀的物理地址计算
例: MOV AX , ES : [ BX ]
使用段跨越的前缀后,段地址由指定的段寄存器给出 ,
不再遵循默认关系。
PA = ( ES ) × 10H + ( BX )
而不等于≠ ( DS ) × 10H + ( BX )
65
只有存储器操作数需用段跨越的前缀
MOV ES : [SI] , CX
MOV AL , DS : [BP]
MOV ES : AX , 0
CS: MOV CX, 22H ;DEBUG
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位偏移量
67
除此之外,其他方式均错误。
如 MOV CL, [AX]
MOV AX, [DX]
MOV AL, [CX]
MOV CX, [BP+BX]
MOV AH, [SI+DI]
MOV BL, [AX+CX]
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
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
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
71
四、 I/O 端口寻址
直接端口寻址采用这种寻址方式时,端口地址只有 8位( 0~0FFH)。例如:
IN AL , 10H ;从 10H 号端口读入 8位数据OUT 50H , AX ;把 AX 中的内容送到 50H 号端口IN EAX , 20H ;从 20H 号端口读入 32位数据
72
I/O 端口寻址 间接端口寻址:采用这种寻址方式时,端口地址
为 16位( 0~0FFFFH)。 必须先将端口地址存放到寄存器 DX 中。
例如:MOV DX , 1000H;端口地址为 1000H
OUT DX , AL ;间接端口寻址
73
.壹 概述
.贰 数据传送指令
.叁 算术运算指令
.肆 逻辑运算指令
.伍 控制转移指令
.陆 处理机控制指令
.柒 串操作指令
第二节 80x86 指令系统
74
一.概述
1. 指令助记符表
2. 学习指令的要点
3. 利用 DEBUG 程序,学习指令系统
4. 指令中操作数的表示
5. 书写指令注意事项
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. 指令助记符表
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
77
2. 学习指令的要点
从以下几个方面来掌握一条指令 : 指令的助记符 指令的格式:操作数的个数、类型 执行的操作:指令执行后的结果包括 : 哪些寄存器、内存单元的值发生了变化
对标志位有无影响,哪些受影响 特点及注意事项
只介绍常用的指令,其他需要时可自学。
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
两操作数
79
5. 书写指令注意事项:
不区分字母的大小写。
下列写法表示同一条指令:
MOV AX, 1ABDH
mov ax, 1abdh
不添加指令系统没有的指令,即不自创助记符。
将 MOV AL , 0 写成 MOVE AL , 0
JMP lable 写成 JUMP lable
80
注意操作数的范围
对字节操作指令 0 ~ FFH 0 ~ 255
对字操作指令 0 ~ FFFFH 0 ~ 65535
MOV AL , 260 MOV AX , 70000 MOV AL, 1FFH MOV AL, 2ABCDH
81
对无操作数指令,不添加操作数。
STC AL
对单操作数指令,操作数不能是立即数。
IMUL 6
82
对双操作数指令
① 不能两个同为存储器操作数 MOV [ DI ] , [ SI ]
② 目的操作数不能是立即数 ADD 3 , AL ③ 两个操作数的类型应相同 SUB AX , BL
若 value 定义为字类型存储器变量:
MOV CL, value [ BX ]
83
内存操作数的属性应明确。
MOV [ BX ] , 0
MOV byte ptr [ BX ] , 0
MOV word ptr [ BX ] , 0
MOV [ BX ] , AL
MOV [ BX ] , AX
84
A 、 B 、 C 、 D 、 E 、 F 开头的十六进制数前面加 0 ,
与 H 结尾的标识符区别。
如 寄存器名 AH 、 BH 、 CH 、 DH
变量名 abcdH 等
例 mov AL, 0AH
mov AL, AH
mov BX, 0abcdH
85
CS 和 IP 的值只在控制转移指令中修改。
对非控制转移指令,取完指令后 IP 值自动 指向下条指令。
段寄存器 CS 的值,只在 MOV 、 PUSH 中可作操作数, 且这两条指令执行结果不改变 CS 值。
MOV AX, CS
PUSH CS
IP 、 PSW 两个寄存器不作为操作数在指令中出现。mov IP , 1234H
mov PSW , 0F0FH
PSW状态寄存器的值由指令执行后确定, 不同的指令对各标志的影响不同。
86
一 . 数据传送指令
存储器
I/O接口
输入设备
I/O接口
数据总线 DB
控制总线 CB
地址总线 AB
输入设备
CPU
寄存器,存储器, I/O 端口
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端口
设置寄存器、内存单元的初始值
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 这三条允许
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 )
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
91
MOV 指令特点及注意事项 :
双操作数指令 ( 注意双操作指令的特点)
可进行字节或字传送 不允许存储器传送到存储器
MOV [ BX ] , value
MOV [DI] , [SI]
MOV AX , value
MOV [ BX ] , AX
MOV AL , [SI]
MOV [ DI ] , AL
92
可对 DS 、 ES 、 SS 赋值 但不允许立即数直接传送给段寄存器
MOV DS , AX
MOV ES , [BX]
MOV DS , 1000H
MOV AX , 1000H
MOV DS , AX
CS 不能做目的操作数 , 不能通过传送指令改变 CS 的值
MOV CS , AX
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-
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)
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 变不变
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
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
变 变
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
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
100
堆栈是一个内存区域。 通常用于存放一些重要数据 ,
如程序的地址、或是需要恢复的数据。 SS:SP
为方便数据的存放和恢复, 设置专门的指针,指向堆栈中要操作的单元。 段值由 SS 给出,偏移地址由 SP 给出
SS → 堆栈段寄存器 (stack segment)
SP → 堆栈指针寄存器 (stack point)
堆栈的概念 stack
101
堆栈操作指令 PUSH 和 POP , 对 SS 和 SP 指向的内存单元, 以“后进先出”方式进行操作。
PUSH → 入栈操作 SP 减小 POP → 出栈操作 SP增加
SP 指向栈顶,即堆栈的顶部,
编程员通过设置堆栈区域, 利用堆栈操作,可方便的进行数据的存放和恢复。
SS:SP
SS:0000
SS:FFFF
堆栈未用空间
102
堆栈使用的场合
用堆栈保存恢复信息 ( 如上例)
子程序的调用、返回以及中断调用、返回 (控制转移指令中介绍)
用堆栈传送数据 (程序设计中介绍)
103
注意事项
堆栈是一重要数据结构,使用堆栈应有明确目的。
不乱用堆栈操作,不乱修改堆栈内容。
PUSH 、 POP 、 PUSHF 、 POPF 、
CALL 、 RET 、 INT 、 IRET
乱修改 SS 和 SP 的内容
包括 乱用 BP参与的存储器操作数
乱用指令
104
PUSH 和 POP 指令只能对字操作。
PUSH AL
POP BYTE PTR [BX]
可以对段寄存器操作 但 POP 不能对 CS 操作
PUSH DS
PUSH CS
POP ES
POP CS
105
4 ) XCHG 交换指令
格式 XCHG oprd1 , oprd2
执行 (oprd1) (oprd2)
reg reg
reg mem
mem reg
可实现
106
例 XCHG AX, BX 字操作
执行前( AX ) = 1122H ( BX ) = 3344H
执行后( AX ) = 3344H ( BX ) = 1122H
例 XCHG AH, BL 字节操作
执行前( AX ) = 1122H ( BX ) = 3344H
执行后( AX ) = 4422H ( BX ) = 3311H
107
XCHG oprd1 , oprd2
注意事项 :
双操作数指令
可进行字或字节操作
不允许对立即数、段寄存器做操作数
XCHG AX, 4
XCHG BX, DS
108
2. 地址传送指令 LEA 、 LDS 、 LES
LEA 有效地址传送
格式 LEA reg, mem
执行 ( reg ) ← mem 的 EA
即 寄存器 ← 存储器操作数的偏移地址
109
执行后 ( BX ) = 1000H
注意:
OFFSET 是汇编程序提供的一个操作符,不是 CPU 的指令
LEA BX, buffer
例 buffer 是一个符号地址表示的内存操作数 ( 变量 ) 。
…...12h34h56h…...
buffer
内存
DS: 1000h若变量 buffer 的偏移地址 = 1000H
等价于 MOV BX , OFFSET buffer
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 为偏移值的内存单元
111
LEA reg, mem
特点及注意事项:
目的操作数 reg 应是 16 位通用寄存器 LEA ES, [BX]
LEA AL, buffer
LEA 6, [BX+SI]
LEA [DI], buffer
源操作数应是存储器操作数 LEA BX, AX
传送的是内存单元的有效地址,与其内容无关。
…...12h34h56h…...
buffer
内存
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)
113
特点及注意事项:
无操作数的形式,操作数隐含为 ( PSW)
PUSHF AX
POPF CX
PUSHF 和 POPF 用于标志信息的保存和恢复
114
二 . 算术运算指令
二进制运算 十进制调整
加 ADD, ADC, INC AAA, DAA
减 SUB, SBB, DEC, NEG, CMP AAS, DAS
乘 MUL, IMUL AAM
除 DIV, IDIV AAD
符号扩展指令: CBW、CWD
指令分类:
115
特点: 带符号数用补码表示 如 MOV AX, -1 等价于 MOV AX, 0FFFFh
对加、减运算,不区分无符号数、带符号数 对乘、除运算,区分无符号数、带符号数 可进行字节或字操作 影响状态标志 十进制运算方法
当数据用压缩或非压缩 BCD码表示时,为使运算的结果仍为 BCD码表示,需对结果进行调整。 十进制运算 = 二进制运算 + 十进制调整
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
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 字节
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
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
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 的判断方法 )
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 计算时不区分无符号数、带符号数
122
例 2 INC AL
执行前 ( AL) = FFH
执行后 :
( AL) =00H
CF= 不变, OF=0 , ZF=1 , SF=0
FFH + 01H 11 00H
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]
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
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 只能按字节或字相加。 位数在字以上的操作数,先加低位,再加高位, 加高位时加入从低位产生的进位。
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 减去该操作数的过程决定。
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
借位
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
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
130
例 4 用指令完成两双字相减运算
0546 7A70H - F001 A543H
MOV AX , 7A70H
SUB AX , A543H
MOV BX , 0546H
SBB BX , 0F001H
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 ,进行两操作数相减操作, 但只影响标志值,不影响操作数 ( 减的结果不保存 )
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 中
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 ,溢出情况,( 由符号位可决定是否溢出 )
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
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: 、、、
136
3. 乘法指令
指令格式 执行操作
MUL src
若 src为字节类型: (AX) ← (AL)× (src) 若 src为字类型: (DX),(AX) ← (AX)× (src)
将被乘数、乘数看作无符号数,进行乘运算 乘的结果也为无带符号数
IMUL src 执行的操作与MUL相似 将被乘数、乘数看作带符号数, 进行乘运算 乘的结果也为带符号数
无符号数乘法
带符号数乘法
137
MUL src
IMUL src
单操作数指令 源操作数 ( 乘数 ) 类型决定操作类型 目的操作数 ( 被乘数 ) 隐含。 字节乘 AL 字乘 AX
字节相乘的结果存放在 AX 中 字相乘的结果存放在 DX 、 AX 中 MUL 用于无符号数运算 IMUL 用于带符号数运算
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
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
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
141
4. 除法指令
指令格式 执行操作
DIV src
无符号数除法
(src)为字节类型:
(AL) ← (AX) / (src) 的商
(AH) ← (AX) / (src) 的余数
(src)为字类型:
(AX) ← DX) , (AX) / (src) 的商
(DX) ← (DX) , (AX) / (src) 的余数
将被除数、除数看作无符号数,进行除法运算,
商、余数也为无符号数
IDIV src
带符号数除法
执行的操作与 DIV相同,
将被除数、除数看作带符号数,进行除法运算
商、余数也为带符号数,余数的符号与被除数同
142
单操作数指令 源操作数 ( 除数 ) 类型 决定指令操作类型 目的操作数 (被除数 )隐含 字节操作在 AX 中;字操作在 DX, AX 中 除的结果,字节操作在 AX 中;字操作在 DX, AX中 除法指令对所有条件码位均无定义 下列情况自动转入 0 中断处理: (1) 除数为 0
(2) 字节操作,商的范围超出字节范围 字操作时,商的范围超出字范围
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
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
145
无操作数格式 操作数隐含
字节操作,源在 AL ,目的在 AX字 操 作,源在 AX ,目的在 DX,AX
对条件码无影响 符号扩展指令应对带符号数操作 扩展后,表示的数值大小不变,只是位数发生变化 8 位 16 位 16 位 32 位 应用场合: 除法指令中,使被除数满足要求。
字节操作,被除数为 16 位字操作,被除数为 32 位
加减运算中,使两操作数类型一致如:字与字节相加、减时
如:双字与字之间的相加、减时
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 。
147
BCD 码运算的十进制调整指令 专用于对 BCD 码运算的结果进行调整 包括: AAA 、 DAA 、 AAS 、 DAS 、 AAM 、
AAD 均为隐含寻址,隐含的操作数为 AL 和 AH 为何要对 BCD 码的运算结果进行调整?
BCD码本质上是十进制数,即应遵循逢十进一的规则。而计算机是按二进制(十六进制)进行运算,并未按十进制规则进行运算。
148
8088 的调整指令主要用于十进制数的调整。这些指令包括:
AAA :对 AL 中非压缩 BCD 码求和的结果进行调整。
AAS :对 AL 中非压缩 BCD 码求差的结果进行调整。
AAD :在实现十进制除法时,在除法指令前对 AX 用中非压缩 BCD 码表示的十进制数进行调整。
AAM :在实现十进制乘法时,对 AX 中两个非压缩 BCD码相乘的结果进行调整。
DAA :对 AL 中的两个压缩 BCD 码相加之和进行调整,得到用压缩 BCD 码表示的十进制和。
DAS :对 AL 中的两个压缩 BCD 码相减之差进行调整,得到用压缩 BCD 码表示的十进制差。
148
149
加法的十进制调整指令
非压缩 BCD 码加法调整 AAA本指令对在 AL 中的由两个未组合的 BCD码相加后的结果进行调正,得到一个正确的未组合的 BCD 码。AAA 指令只影响 AF 和 CF ,其余标志无定义。AAA 指令应紧跟在 ADD 或 ADC 指令之后。
149
150
AAA 指令的操作如下:
150
如果 AL 的低 4 位> 9∨AF=1 ,则: ① AL←(AL)+6,(AH)←(AH)+1,AF←1 ② AL←((AL)∧0FH) ③ CF←AF否则 AL←(AL)∧0FH
151
调整原理:先看一个例子 计算 8 + 9 0000 1000 见右式 +0000 1001 0001 0001 = 11
结果应为 17 ,而计算机相加为 11 ,原因在于运算过程中,如遇到低 4 位往高 4 位产生进位时(此时 AF=1 )是按逢十六进一的规则,但 BCD 码要求逢十进一,因此只要产生进位,个位就会少 6 ,这就要进行加 6 调正。
151
这个 1代表了 16 ,而实际上仅应为 10 ,即多进了 6 。
152
实际上当低 4 位的结果> 9( 即 A ~ F 之间 )时,也应进行加 6 调正 ( 原因是逢十没有进位,故用加 6 的方法强行产生进位 ) 。如对上例的结果进行加 6 : 0001 0001 11 + 0000 0110 6 0001 0111 17 ^ 0000 1111---------------------- 1 0000 0111
152
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
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
155155
3) 乘法的十进制调正指令 AAM
对 AX 中由两个非压缩 BCD 码相乘的结果进行调整。调整操作为: (AL)/0AH, (AH)← 商, (AL)← 余数
隐含的操作寄存器为 AL 和 AH ;AAM 跟在 MUL 指令之后使用;影响标志位 PF 、 SF 、 ZF ,其它无定义 ;用 AAM 可实现≤ 99 的二 - 十进制转换。
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
157157
4) 除法的十进制调正指令 AAD
对非压缩 BCD 除法运算进行调整。调整操作为: (AL)←(AH)×0AH + (AL) AH ← 0
隐含的操作寄存器为 AH , AL ;AAD 要在 DIV 指令之前使用;影响标志位 PF 、 SF 、 ZF ,其它无定义 ;用 AAD 可实现≤ 99 的十 - 二进制转换。
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
159
请继续学习 8086系列指令系统…