汇编语言程序设计
Assembly Language Programming





课程介绍
?专业基础课、必修课
?计算机组成原理的一个部分
?软件开发的一个组成部分
?一种低级语言的程序设计
?高级语言程序设计的扩展
相关课程
?先修课
? 高级语言程序设计
? 计算机组成原理
?后续课
? 微机接口技术
? 计算机控制技术
第一章 绪论
? § 1.1 汇编语言程序设计的一般概念
? § 1.2 为什么要学习和使用汇编语言
? § 1.3一个简单的汇编语言源程序举例
? § 1.4计算机中数和字符的表示
§ 1.1 汇编语言程序设计的一般
概念
一、汇编语言
二、汇编语言源程序
三、汇编程序
四、目标程序
五、连接程序
六、调试程序
一、汇编语言
? 汇编语言是一种 面向机器 的 低级 程序设计语言
? 汇编语言以助记符形式表示每一条计算机指令
? 助记符( mnemonic) 是便于人们记忆、并能描述指
令功能和指令操作数的符号
? 助记符一般就是表明指令功能的英语单词或其缩写
? 用助记符表示的指令就是汇编语言中的汇编格
式指令
? 汇编格式指令以及使用它们编写程序的规则就
形成汇编语言( Assembly Language)
二、汇编语言 源程序
? 用汇编语言书写的程序就是汇编语言程序,
或称汇编语言源程序
? 汇编语言源程序以,ASM为默认的扩展名
三、汇编程序( Assembler)
? 汇编程序将汇编语言源程序翻译(称为“汇
编”)成机器代码目标模块
? 80x86CPU的汇编程序主要有微软的宏汇编程序
MASM。 较著名的还有 Borland公司的 TASM,
无实质差别
四、目标程序
? 机器语言程序
? 汇编语言源程序经汇编程序翻译而成
? 不能直接运行
五、连接程序( Linker)
? 连接程序将汇编后的目标模块转换为可执
行程序
? 每个程序开发环境都有连接程序
? 连接程序的文件名通常是,
LINK.EXE
六、调试程序( Debugger)
? 调试程序进行程序排错、分析等
? 本课程采用 DOS的 DEBUG程序
? 其他还有 Turbo Debugger等
源程序 可执行文件 目标模块
文本编辑器 汇编程序 连接程序 调试程序
§ 1.2为什么要学习和使用汇编语

一、汇编语言的主要特点
二、汇编语言可操作的系统硬件资源
三、汇编语言与高级语言之比较
四、汇编语言的应用场合
一、汇编语言的主要特点
? 汇编语言程序与处理器指令系统密切
相关
? 程序员可直接、有效地控制系统硬件
资源
? 形成的可执行文件运行速度快、占用
主存容量少
二、汇编语言可操作的系统
硬件资源
1,中央处理单元
2,存储器(主存储器)
3,外部设备(接口电路)
1、中央处理单元 CPU
( Intel 80x86)
对汇编语言程序员,最关心其中的
寄存器 ( Register)
2、存储器(主存储器)
? 呈现给汇编语言程序员的,是 存储器地址
( Address)
? 存储器是由大量存储单元组成。为了区别每个
单元,我们将它们编号
? 存储器地址是存储器中存储单元的编号
? 微机的每个存储单元存放一个字节的数据
? 一个字节 B( Byte) 包含了 8个二进制位 b( bit)
? 通常采用十六进制数来表达地址
? Intel 8086具有 1兆字节( 1MB) 存储器容量
? 其存储器地址可以表示为,00000H ~ FFFFFH
? 其中大写 H( 或小写 h) 表示是 16进制数
3、外部设备(接口电路)
? 汇编语言程序员看到的是端口( Port)
? I/O接口电路由接口寄存器组成,为了区别它们,
各个寄存器进行了编号,形成 I/O地址。
? 端口就是指 I/O地址,是微机系统对 I/O接口电路
中与程序设计有关的寄存器的编号
? 系统实际上就是通过这些端口与外设进行通讯的
? 通常采用十六进制数来表达端口
? Intel 8086支持 64K个 8位端口
? 其 I/O地址可以表示为,0000H ~ FFFFH
三、汇编语言和高级语言 ( 1)
? 汇编语言与处理器密切相关
↘ 汇编语言程序的通用性、可移植性较差
? 高级语言与具体计算机无关
↗ 高级语言程序可以在多种计算机上编译后
执行
三、汇编语言和高级语言 ( 2)
? 汇编语言功能有限、涉及硬件细节
↘ 编写程序比较繁琐,调试起来也比较困难
? 高级语言提供了强大的功能,不必关心琐
碎问题
↗ 类似自然语言的语法,易于掌握和应用
三、汇编语言和高级语言 ( 3)
? 汇编语言本质上就是机器语言
↗ 可以直接、有效地控制计算机硬件
↗ 易于产生速度快、容量小的高效率目标程序
? 高级语言不针对具体计算机系统
↘ 不易直接控制计算机的各种操作
↘ 目标程序比较庞大、运行速度较慢
三、汇编语言和高级语言 ( 4)
? 汇编语言的优点,
? 直接控制计算机硬件部件
? 可以编写在“时间”和“空间”两方面最有
效的程序
? 汇编语言的缺点,
? 与处理器密切有关
? 需要熟悉计算机硬件系统、考虑许多细节
? 编写繁琐,调试、维护、交流和移植困难
三、汇编语言和高级语言 ( 5)
? 汇编语言的优点使得它在程序设计中占有
重要的位置,是不可被取代的
? 汇编语言的缺点使得人们主要采用高级语
言进行程序开发工作
? 有时需要采用高级语言和汇编语言混合编
程的方法,互相取长补短,更好地解决实
际问题
四、汇编语言的应用场合
? 程序要具有较快的执行时间,或者只能占
用较小的存储容量
? 程序与计算机硬件密切相关,程序要直接、
有效地控制硬件
? 大型软件需要提高性能、优化处理的部分
? 没有合适的高级语言、或只能采用汇编语
言的时候
? 分析具体系统尤其是该系统的低层软件、
加密解密软件、分析和防治计算机病毒等
微机的软件
? 系统软件,DOS平台
? MS-DOS 6.22
? Windows 9.x的 DOS实地址方式
? MS-DOS虚拟环境
? 应用软件:开发汇编语言程序涉及
? 文本编辑器
? 汇编程序
? 连接程序
? 调试程序
? 集成化开发环境
集成化开发环境
? 集成开发环境是进行程序设计所用到的各种软
件的有机集合。其中,有文本编辑器,有语言
翻译程序,有连接程序,还组合有调试程序等。
? 大型的程序设计项目往往要借助这种集成开发
环境,也就是软件开发工具(包)。
? 教材中介绍有集编辑、汇编、连接和调试为一
体的综合开发环境,即 MASM的程序员工作平
台 PWB。
§ 1.3 一个简单的汇编语言源
程序举例
? 分别用 C语言和汇编语言编制一程序,实
现如下功能,
从键盘输入两个 1位整数,将其进行加法运算
并在屏幕上显示加法运算等式(和,=9)。
1 DATA SEGMENT ; 定义数据段
2 A DB 0
3 B DB 0
4 C DB?
5 DATA ENDS
6 PROG SEGMENT ; 定义程序段
7 MAIN PROC FAR ; 定义一远过程
8 ASSUME CS:PROG,DS:DATA
9 START,PUSH DS ; 为返回做准备
10 SUB AX,AX
11 PUSH AX
12 MOV AX,DATA
13 MOV DS,AX
14 MOV AH,01H ;main part of program code goes here
15 INT 21H
16 AND AL,0FH
17 MOV A,AL
18 MOV AH,01H
19 INT 21H
20 AND AL,0FH
21 MOV B,AL
22 ADD AL,A
23 MOV C,AL
24 MOV DL,A
25 ADD DL,30H
26 MOV AH,2
27 INT 21H
28 MOV DL,”+”
29 INT 21H
30 MOV DL,B
31 ADD DL,30H
32 INT 21H
33 MOV DL,“=,
34 ADD DL,30H
35 INT 21H
36 MOV DL,C
37 ADD DL,30H
38 INT 21H
39 RET
40 MAIN ENDP ;Return to DOS
41 PROG ENDS ;End of main part of program
42 END START ;End assembly
§ 1.4 计算机中数和字符的表示
一、数制及数制之间的转换
二、码制
三,BCD码及其表示
四、字符的编码
五、几种基本的逻辑运算
一、数制及数制之间的转换
? 汇编语言使用的数制,
? 十进制数( D)
? 二进制数( B)
? 十六进制数( H)
汇编程序自动完成
二、码制
? 计算机中的数是用补码表示的
? 带符号数的表示范围(补码)
n位二进制数
-2 n-1 ≦ N ≦ 2 n-1-1
8位二进制数,-128 —+127
16位二进制数,-32768 — +32767
三,BCD码及其表示
7 6 5 4 3 2 1 0
BCD 无意义
7 6 5 4 3 2 1 0
BCD BCD
个 位 十 位
?用 4位二进制数表示 1位 十进制数
?常用的 BCD码存储格式
?组合(压缩)型 BCD码( 1Byte表示 2个 BCD码)
?非组合(非压缩)型 BCD码( 1Byte表示 1个 BCD码)
四、字符的编码
? 采用 7位编码的 ASCII码,用 1Byte表示
非打印字符 33个(用于控制)
? 27=128
打印字符 95个
BEL(07H) 响铃
DEL(7FH) 删除
CR (0DH) 回车
LF (0AH) 换行
五、几种基本的逻辑运算
?,与”运算( AND )
?“或”运算( OR )
?“非”运算( NOT)
?“异或”运算( XOR)
第二章 80x86计算机组织
§ 2.1 80x86微处理器
§ 2.2 基于微处理器的计算机系统构成
§ 2.3 中央处理机
§ 2.4 存储器
§ 2.5 外部设备
§ 2.1 80x86微处理器
§ 2.2 基于微处理器的计算机
系统构成
系统资源,CPU,存储器,I/O端口
§ 2.3 中央处理机
一,Intel 8088/8086微处理器的功能结构
1.编程结构
2.工作过程
二,8086/8088的寄存器组
1.通用寄存器
2.段寄存器
3.控制寄存器
内部暂存器
IP
ES
SS
DS
CS
输入 /输出
控制电路



线
执行部分
控制电路
1 2 3 4 5 6

ALU
标志寄存器
AH AL
BH BL
CH CL
DH DL
SP
BP
SI
DI
通用寄存器
地址加法器
指令队列缓冲器
执行部件 ( EU) 总线接口部件 ( BIU)
16位
20位
16位
8位
8086编程结构
编程结构
? BIU( 总线接口部件)
? 负责与存储器及 I/O设备交换信息 指令
数据
? EU( 执行部件)
? 负责指令的执行
工作过程
两部分并行工作,提高了工作效率
? 每当指令队列中有两个空字节,BIU自动把内存中的指
令送入指令队列中
? EU从指令队列中取出指令代码去执行(此时,BIU可继
续取指)。如在指令执行过程中需要访问存储器或 I/O
设备,则 EU会请求 BIU进入总线周期,去完成访问存储
器或 I/O端口的操作
? BIU处于空闲状态,则立即响应 EU的总线请求
? BIU正在取指,完成当前取指操作后响应 EU的请求
? 当指令队列已满,且 EU没有总线请求时,BIU进入空
闲状态
? 在执行转移、调用和返回指令时,BIU指令队列的原有
内容会被自动清除,而装入转移目标处的指令。
二,8086/8088的寄存器组
? 是基本资源,亦是操作对象。对内部寄存器的
使用尤为重要,可实现的操作多
速度快
1.通用寄存器
2.段寄存器
3.控制寄存器
1.通用寄存器
8个 16位寄存器位于 EU中
? 数据寄存器(共 4个 16位)
? 指针及变址寄存器(共 4个 16位)
内部暂存器
IP
ES
SS
DS
CS
输入 /输出
控制电路



线
执行部分
控制电路
1 2 3 4 5 6

ALU
标志寄存器
AH AL
BH BL
CH CL
DH DL
SP
BP
SI
DI
通用寄存器
地址加法器
指令队列缓冲器
执行部件 ( EU) 总线接口部件 ( BIU)
16位
20位
16位
8位
1.通用寄存器 — 数据寄存器
? AX(Accumulator)累加器,算术运算的主要 R,所有
的 I/O指令都用此 R
? BX(Base)基址寄存器,除通用外,计算存储器地址
做基址用
? CX(Count)计数器,通用,作循环计数器
? DX(Data)数据寄存器,常用来存放双字长数据的高
16位,或存放外设端口地址
? 特点,
? 可作 16位 R使用,也可将每个拆成 2个 8位寄存器使用,
对其中某 8位的操作,并不影响另外对应 8位的数据
? 具有良好的通用性:在程序中即可存放操作数,也可
存放操作结果
1.通用寄存器 — 指针及变址寄存器
变址寄存器
? SI(Source Index)源变址寄存器
? DI(Destination Index)目的变址寄存器
指针寄存器
? SP(Stack Point)堆栈指针寄存器 —栈顶的偏移地

? BP(Base Point)基址指针寄存器 —默认 SS段
特点,
可用于存放操作数,但只能作为 16位 R使用
2.段寄存器
? 4个 16 bits Segment Registers
? 在 8086/8088系统中,存储器是按段进行组
织的,段寄存器就是用来存放段基值的
(段起始地址的高 16位)
? 运行程序时所必要的指令、数据等存放于
内存的不同段内,根据其用途的不同,又
不同的段寄存器指示,并称其为 当前段
内部暂存器
IP
ES
SS
DS
CS
输入 /输出
控制电路



线
执行部分
控制电路
1 2 3 4 5 6

ALU
标志寄存器
AH AL
BH BL
CH CL
DH DL
SP
BP
SI
DI
通用寄存器
地址加法器
指令队列缓冲器
执行部件 ( EU) 总线接口部件 ( BIU)
16位
20位
16位
8位
2.段寄存器
? CS,代码段寄存器 —对应的段存放指令代码
? DS,数据段寄存器 —对应的段存放数据或变

? SS,堆栈段寄存器 —对应的段存放栈操作的
数据
? ES,附加段寄存器 —对应的段一般存放数据
或变量
整个内存可划分为多个段,但当前段最多只
能有 4个,如果需要改变当前段,则可通过程序
修改段寄存器的内容
内部暂存器
IP
ES
SS
DS
CS
输入 /输出
控制电路



线
执行部分
控制电路
1 2 3 4 5 6

ALU
标志寄存器
AH AL
BH BL
CH CL
DH DL
SP
BP
SI
DI
通用寄存器
地址加法器
指令队列缓冲器
执行部件 ( EU) 总线接口部件 ( BIU)
16位
20位
16位
8位
3.控制寄存器
3.控制寄存器 — IP
? IP(Instruction Pointer)指令指针寄存器 IP (16bits)
?指示代码段中指令的偏移地址
?它与代码段寄存器 CS联用,确定下一条指令的物理地址
?计算机通过 CS, IP寄存器来控制指令序列的执行流程
?IP寄存器是一个专用寄存器
?不能对 IP指针直接进行访问
程序顺序执行
修改 转移指令的执行
调用、返回指令的执行
CS
IP
正在执行的指令
下一条将要执行的指令
16 bits 偏移量
XX
XX
XX
XX
XX
XX
XX
XX
3.控制寄存器 — FLAGS
? 标志( Flag) 用于反映指令执行结果或控
制指令执行形式
? 8086处理器的各种标志形成了一个 16位的
标志寄存器 FLAGS( 程序状态字 PSW寄存
器 )
OF
11 15 12
DF
10
IF
9
TF
8
SF
7
ZF
6 5
AF
4 3
PF
2 1
CF
0
标志位的分类
? 状态标志 ( 6),表示前面的操作执行后,ALU所
处的状态,将影响后面的操作
? 控制标志 ( 3),用专门的指令进行设置,用于控
制处理器执行指令的方式
OF
11 15 12
DF
10
IF
9
TF
8
SF
7
ZF
6 5
AF
4 3
PF
2 1
CF
0
标志位的功能 —进位标志 CF( Carry Flag)
? 记录运算时从最高有效位产生的进 /借位值
3AH + 7CH= B6H,没有进位,CF = 0
AAH + 7CH=( 1) 26H,有进位,CF = 1
0 NC 没有产生进 /借位
1 CY 有进 /借位产生 CF=
标志位的功能 —零标志 ZF( Zero Flag)
0 NZ 结果非零
1 ZR 结果为零 ZF=
3AH + 7CH= B6H,结果不是零,ZF = 0
84H + 7CH= ( 1) 00H,结果是零,ZF = 1
注意,ZF为 1表示的结果是 0
标志位的功能 —符号标志 SF( Sign Flag)
? 表明有符号数运算结果的正负
0 PL 结果为正
1 NG 结果为负 SF=
有符号数据用最高有效位表示数据的符号
所以, 最高有效位就是符号标志的状态
3AH + 7CH= B6H,最高位 D7= 1,SF = 1
84H + 7CH= ( 1) 00H,最高位 D7= 0,SF = 0
标志位的功能 —奇偶标志 PF( Parity Flag)
? 表明运算结果最低字节中, 1” 的个数的奇
偶 0 PO, 1” 的个数为奇数
1 PE, 1” 的个数为偶数 PF=
3AH + 7CH= B6H= 10110110B
结果中有 5个 1,是奇数,PF = 0
PF标志仅反映最低 8位中, 1” 的个数是
偶或奇, 即使是进行 16位字操作
标志位的功能 —溢出标志 OF( Overflow Flag)
? 表明补码的运算结果是否有溢出
0 NV 没有溢出
1 OV 溢出 OF=
3AH + 7CH= B6H,产生溢出,OF = 1
AAH + 7CH= ( 1) 26H,没有溢出,OF = 0
关于溢出
? 处理器内部以补码表示有符号数
? 8位表达的整数范围是,- 128 ~ + 127
? 16位表达的范围是,- 32768 ~ + 32767
? 如果运算结果超出这个范围,就产生了溢出
? 有溢出,说明有符号数的运算结果不正确
3AH+ 7CH= B6H,就是 58+ 124= 182,
已经超出- 128~+ 127范围,产生溢出,故 OF= 1;
另一方面,补码 B6H表达真值是 -74,
显然运算结果也不正确
溢出和进位
? 溢出标志 OF和进位标志 CF是两个意义不
同的标志
? 进位标志表示无符号数运算结果是否超出
范围,运算结果仍然正确;
? 溢出标志表示有符号数运算结果是否超出
范围,如溢出,运算结果已经不正确。
溢出和进位的对比
例 1,3AH + 7CH= B6H
无符号数运算,58+ 124= 182
范围内,无进位
有符号数运算,58+ 124= 182
范围外,有溢出
CF=0 OF=1
例 2,AAH + 7CH= ( 1) 26H
无符号数运算,170+ 124= 294
范围外, 有进位
有符号数运算,- 86+ 124= 28
范围内, 无溢出
CF=1 OF=0
如何运用溢出和进位
? 处理器对两个操作数进行运算时,按照无
符号数求得结果,并相应设置进位标志 CF;
同时,根据是否超出有符号数的范围设置
溢出标志 OF。
? 应该利用哪个标志,则由程序员来决定。
也就是说,如果将参加运算的操作数认为
是无符号数,就应该关心进位;认为是有
符号数,则要注意是否溢出。
标志位的功能 —
辅助进位标志 AF( Auxiliary Carry Flag)
? 记录运算时 D3位(低半字节)有无进位或
借位
0 NA D3未产生进 /借位
1 AC D3产生进 /借位 AF=
3AH + 7CH= B6H,D3有进位,AF = 1
这个标志主要由处理器内部使用, 用于十进
制算术运算调整指令中, 用户一般不必关心
标志位的功能 —方向标志 DF( Direction Flag)
? 用于串操作指令中,控制地址的变化方向
0 UP 存储器地址自动增量修改
1 DN 存储器地址自动减量修改 DF=
?CLD指令复位方向标志,DF= 0
?STD指令置位方向标志,DF= 1
标志位的功能 —中断允许标志 IF( Interrupt-enable Flag)
? 用于开中断或屏蔽中断
0 DI 关中断,禁止响应中断
1 EI 开中断,允许响应中断 IF=
?CLI指令复位中断标志,IF= 0
?STI指令置位中断标志,IF= 1
标志位的功能 —陷阱标志 TF( Trap Flag)
? 用于控制处理器进入单步操作方式
0 处理器正常工作
1 处理器单步执行指令
? 单步执行指令 —— 处理器在每条指令执行结束时,
便产生一个编号为 1的内部中断
? 这种内部中断称为单步中断
? 所以 TF也称为单步标志
? 利用单步中断可对程序进行逐条指令的调试
? 这种逐条指令调试程序的方法就是单步调试
§ 2.4 存储器
一、存储器的组成
二、存储器的段结构
三、逻辑地址与物理地址
四、堆栈
一、存储器的组成
1,存储器的编址
2,数据的存储
3,8086/8088对内存的访问
由若干个存储单元组成,存储单元的多少代表存储器的容量
每个存储单元存储 8个 2进制位 — 容量用 Byte数来衡量
1.存储器的编址
?8086 CPU 有 20条地址线
? 最大可寻址空间为
220= 1MB
? 物理地址范围
00000H~ 0FFFFFH
? 存储单元连续编号,被
称为存储器地址
00000H
00001H
00002H
00003H
0FFFFDH
0FFFFEH
0FFFFFH
2.数据的存储
? 字节 (Byte)
每个字节占据 1个存储单元 ( 09234H) =78H
? 字 (Word)
? 任何两个相邻的字节构成 1个 Word
? 存放形式:高地址单元对应高位字节,低地址单元对
应低位字节
? 字的地址:用地址较小的字节单元的地址作为该字单
元的地址
? ( 09235H) =3456H ( 09236H) =1234H
? 双字 (DWord)
? 两个相邻的字单元构成 1个双字 (09234H)=12345678H
78H
56H
34H
12H
09234H
09235H
09236H
09237H
字单元的地址可为奇数也可为偶
数, 但由于机器中对字单元的访问是
以偶地址进行的, 故若设字地址为奇
地址, 则需进行两次存储器访问
3.对内存的访问
? 8086 字节

? 80386 双字
由指令明确规定或由指令中所使用的
变量名(存储单元的符号地址)的类型决
定,变量名的类型是事先定义的。
二、存储器的段结构
? 8086 CPU 有 20条地址线,存储器地址是 20位的
? 8086 的内部寄存器(包括 IP) 都是 16位的
? 无法用寄存器直接对 1MB的内存空间直接进行寻

引入分段的概念 —实模式存储器寻址
1,1MB的存储空间可由用户根据需要划分成若干
个逻辑段( Segment)
2,每个段的容量 ≦ 64KB,连续的存储单元。(段
内是 16位的寻址,0000H—0FFFFH)
3,每段地址最小的字节单元的地址为该段的段 基
址 (首地址),要求其最低 4位为 0(如:
00000H,00010H,000F0H,等)
4,段与段之间的关系:邻接、间隔、部分重叠、
完全重叠。(一个物理存储单元可以映象到一
个或多个逻辑段中
5,某一时刻,系统只允许访问 4个段中的内容(由
4个段寄存器指示,其中存放段首址的高 16位 —
段基值)
6,如果程序 /数据较大(〉 64KB) 可修改段寄存器
的内容来访问其他段

1

2

3

4
段 5
邻接
部分重叠
完全重叠
间隔
三、逻辑地址与物理地址
1,物理地址
? 即 20位的地址编码,每个存储单元有唯一的物理地址
? 信息的传送是通过它来寻址存储单元并进行传送
2,逻辑地址
? 程序设计中使用的是逻辑地址
? 由于段可重叠,同一个存储单元可以有多个逻辑地址
? 段基值:段起始单元地址的高 16位,其值存放于段寄存器中
? 偏移量:某存储单元与它所在起始单元之间的距离,以字节数计
? 偏移量为 0:该单元就是段的起始单元
? 偏移量的最大值,0FFFFH( 0—0FFFFH共 64K个)
? 逻辑地址的表示方式
? 段基值:偏移量
内部暂存器
IP
ES
SS
DS
CS
输入 /输出
控制电路



线
执行部分
控制电路
1 2 3 4 5 6

ALU
标志寄存器
AH AL
BH BL
CH CL
DH DL
SP
BP
SI
DI
通用寄存器
地址加法器
指令队列缓冲器
执行部件 ( EU) 总线接口部件 ( BIU)
16位
20位
16位
8位
三、逻辑地址与物理地址
3,逻辑地址与物理地址的逻辑关系
? 当 CPU访问存储器时,BIU将逻辑地址转换为
物理地址
? 物理地址 =段基值 × 16+偏移量
16位段基值
16位偏移量
0000
15 0
15 0
+
20位物理地址 20 0
所选存储单元 ⊕
20位物理地址
20 0
16位段基值
15 0
0000
16位偏移量
15 0
所选段
3,逻辑地址与物理地址的逻辑关系
逻辑地址 1460H:0100H,1380H:0F00H
14600H
+ 100H
14700H
段地址左移 4位
加上偏移地址
得到物理地址
13800H
+ F00H
14700H
物理地址 14700H
段的分配
? 例:如代码段程序占用 8KB(2000H)存储区,
数据段占用 2KB(800H)存储区,堆栈段占用
256B存储区。内存应如何分配。
? 每段均小于 64KB,且总占用量小于 1MB
? 可有多种分配方案
代码段
堆栈段
数据段
附加段
0150H CS
4200H DS
1CD0H SS
B000H ES
01500H
42000H
1CD00H
B0000H
每段占用 64KB,且段间间隔,
所占用空间远多于实际需要。
8KB代码段
2KB数据段
256B堆栈段
0200H CS
0400H DS
0480H SS
ES
02000H
04000H
04800H
段间邻接
此例中每段的长度都是 16的整
数倍,可邻接;若不满足此要
求,则下一段将从最近的第一
个小段开始,中间有少于 16
Bytes 的间隔
4,逻辑地址的来源
? 程序运行中所需要的指令、数据根据用途
不同存放在内存的不同段中,对内存进行
访问时根据操作类型的不同,通过不同的
途径给出逻辑地址,以获得物理地址。
SI,DI等
?取指 CS IP
?堆栈 SS SP
?数据 DS
CS
ES
SS
SS
Bottom
AH
AL
SP
SP=SP-2
XX
XX
AH AL
AX BX
PUSH AX POP BX
AH AL
SP=SP+2
第 3章 80x86的指令系统和寻址方式
§ 3.1 80x86的寻址方式
§ 3.3 80x86的指令系统
§ 3.4 80x86的机器语言指令概况
基本概念 —指令系统
每一种计算机都有一组指令集供用户
使用,这组指令集称为该计算机的指令系
统。指令集中的每条指令在汇编语言中都
是用助记符来表示的。
基本概念 —指令的构成
? 指令由操作码和操作数两部分组成
? 操作码 说明计算机要执行哪种操作,如传送、
运算、移位、跳转等操作,它是指令中不可缺
少的组成部分
? 操作数 是指令执行的参与者,即各种操作的对

? 有些指令不需要操作数,通常的指令都有一个
或两个操作数,也有个别指令有 3个甚至 4个操
作数
操作码 操作数
基本概念 —8086指令的基本格式
? 操作码 [目的操作数 ][,源操作数 ]] [;注释 ]
DEST SRC
? [ ]内的内容可缺省
? 书写注意事项,
?操作码与操作数至少有一个空格或制表
符分隔
?操作数之间必须用“,”相分隔,DEST
在前,SRC在后
? 每种指令的 操作码,
? 用一个唯一的助记符表示(指令功能的英文
缩写)
? 对应着机器指令的一个二进制编码
? 指令中的 操作数,
? 可以是一个具体的数值
? 可以是存放数据的寄存器
? 或指明数据在主存位置的存储器地址
基本概念 —寻址方式
? 在指令中为了取得操作数地址所使用的方式
? 寻找操作数的过程就是操作数的寻址
? 不同的指令系统都规定一些寻址方式供编程时
选用
? 指令的寻址方式主要由操作数的形式表示出来
? 操作数采取哪一种寻址方式,会影响机器运行
的速度和效率
§ 3.1 80x86的寻址方式
一、与数据有关的寻址方式
二、与转移地址有关的寻址方式
1,立即(数)寻址
2,寄存器寻址
3,直接寻址
4,寄存器间接寻址
5,寄存器相对寻址
6,基址变址寻址
7,相对基址变址寻址
1.立即(数)寻址
? 指令中的操作数直接存放在机器代码中,紧跟
在操作码之后(操作数作为指令的一部分存放
在操作码之后的主存单元中)
? 这种操作数被称为立即数 imm
? 它可以是 8位数值 i8( 00H~ FFH)
? 也可以是 16位数值 i16( 0000H~ FFFFH)
? 立即数寻址方式常用来给 R/M赋值
? 立即数只能用于源操作数
立即数寻址指令
MOV AL,05H ; AL←05H
MOV AX,0102H ; AX←0102H
立即数寻址的功能
立即数寻址的执行
2,寄存器寻址
? 操作数存放在 CPU的内部寄存器 reg中,可
以是,
? 8位寄存器,
AH,AL,BH,BL,CH,CL,DH,DL
? 16位寄存器,
AX,BX,CX,DX,SI,DI,BP,SP
? 4个段寄存器 seg,
CS,DS,SS,ES
MOV AX,1234H ; AX←1234H
MOV BX,AX ; BX←AX
寄存器寻址的功能
寄存器寻址的执行
存储器操作数的寻址
? 当操作数存放在内存中时,寻找操作数归结为
如何确定存储单元的地址
? 逻辑地址 段基值:偏移量
由段寄存器的内容给出 主要确定该部分的内容 (EA)
? 物理地址 =(段寄存器) × 16 + EA
位移量:指令中给出 16位数(常数、符号)
EA 基地址:有基址寄存器 BX或基址指针 BP给出
由变址寄存器( SI或 DI) 给出
在实际寻址过程中, 可能包含不同部分,
EA为它们的相加之和, 可在 64KB范围内寻
址 。 构成 EA的 3个分量的不同组合, 形成了
不同的寻址方式 。
3,直接寻址
? 有效地址在指令中直接给出
操作数的 16位偏移量直接包含在指令中,与操作码
一起放在代码段中
? 用符号表示的位移量
MOV BX,VAR ← → MOV BX,DS:VAR; 表示将用符号 VAR表示的字单元的内容 → AX;不声明段则默认为数据段,指明段寄存器则可实现
段跨越
? 用常数表示的位移量
MOV AX,DS:[2000H]; 表示将数据段偏移 2000H字节的字单元的内容 → AX
直接寻址的功能
MOV AX,DS:[2000H]
直接寻址的执行
MOV AX,DS:[2000H]
4,寄存器间接寻址
? 有效地址存放在寄存器中,如 BX,BP,SI,DI
? 所使用的寄存器相当于地址指针,当修改其内
容后可指向不同的存储单元
? 书写时用 []括住寄存器名,以区别于寄存器寻址
? 若以 BX,SI,DI间址,操作数默认在数据段;
若以 BP间址,操作数默认在堆栈段;使用段超
越前缀改变段
MOV AX,[SI] ← → MOV AX,DS:[SI]
MOV CL,[BX] ← → MOV CL,DS:[BX]
MOV BL,[BP] ← → MOV BL,SS:[BP]
寄存器间接寻址的功能
寄存器间接寻址的执行
5.寄存器相对寻址方式
? 直接变址寻址,基址寻址,变址寻址
? 有效地址是寄存器内容与有符号 8位或 16位位移
量之和,寄存器可以是 BX,BP或 SI,DI
EA = BX/BP 或 SI/DI + 0/8/16位位移量
? 段地址对应 BX/SI/DI寄存器默认是 DS,对应 BP
寄存器默认是 SS; 可用段超越前缀改变
? 该方式不仅可以修改指针,还可以修改位移量,
对数组操作十分方便
基址寻址
变址寻址
5.寄存器相对寻址方式
MOV AX,10H[SI] ← → MOV AX,DS:10H[SI]
MOV AX,ARRAY[BX] ← → MOV AX,DS:ARRAY[BX]
MOV TABLE[DI],AL ← → MOV DS:TABLE[DI],AL
MOV TABZ[BP],BL ← → MOV SS:TABZ[BP],BL
寄存器相对寻址的功能
寄存器相对寻址的执行
代码段
DS
数据段
操作码
24H
00H
12H
34H
56H
78H
9AH
MOV AL,0024H[SI]
0024H
(SI)=0 (AL)=12H
(SI)=1 (AL)=34H
(SI)=2 (AL)=56H
(SI)=3 (AL)=78H
(SI)=4 (AL)=9AH
EA=24H+(SI)
(SI)
可看作数据起始单元
的偏移量
数组内某元素距数组
起始单元的偏移
通过修改 SI可遍历整个数组
6.基址变址寻址方式
? 有效地址由基址寄存器( BX或 BP) 的内
容加上变址寄存器( SI或 DI) 的内容构成,
EA= BX/BP+ SI/DI
? 段地址对应 BX基址寄存器默认是 DS,对
应 BP基址寄存器默认是 SS; 可用段超越
前缀改变
6.基址变址寻址方式
MOV AX,[BX][SI] ← → MOV AX,DS:[BX+SI]
MOV AX,[BP][DI] ← → MOV AX,SS:[BP+DI]
MOV AX,DS:[BP][DI] ← → MOV AX,DS:[BP+DI]
基址变址寻址的功能









基址变址寻址的执行









7.相对基址变址寻址方式
? 有效地址是基址寄存器( BX/BP),变址寄存
器( SI/DI) 与一个 8位或 16位位移量之和,
EA= BX/BP+ SI/DI+ 8/16位位移量
? 该方式中,BX/BP选一,SI/DI选一
? 段地址对应 BX基址寄存器默认是 DS,对应 BP
基址寄存器默认是 SS; 可用段超越前缀改变
7.相对基址变址寻址方式
MOV AX,06H[BX+SI] ← → MOV AX,DS:[BX+SI+06H]
MOV AL,TAB[BX][DI] ← → MOV AL,DS:TABLE[BX][DI]
MOV DWORD[BP][SI],DX ← → MOV SS:DWORD[BP][SI],DX
MOV AX,ARRAY[BX][BP] ×
MOV AX,DA[SI][DI] ×
31A00
3000:1A00
BX,SI分别存放数组的脚标
MOV AL,ARRAY[BX][SI]
DS
数据段
ARRAY
SI
BX
二维数组起始单元

EA
[ ]之间表示相加的关系
[BX][SI] ← → [BX+SI]
二、与转移地址有关的寻址方式
程序代码亦存放在存储器中,如
何控制程序的走向(转移位置的地
址 CS:IP) 是本部分所涉及的内容
?直接寻址方式
? 转移地址象立即数一样,直接在指令的
机器代码中,就是直接寻址方式
?间接寻址方式
? 转移地址在寄存器或主存单元中,就是
通过寄存器或存储器的间接寻址方式
用标号表达
用寄存器或存储
器操作数表达
目标地址的范围:段内
? 段内转移 —— 近转移( near)
? 在当前代码段 64KB范围内转移
( ± 32KB范围)
? 不需要更改 CS段 基值,只要改变
IP偏移地址
? 段内转移 —— 短转移( short)
? 转移范围可以用一个字节表达,
在段内- 128~+ 127范围的转移






目标地址的范围:段间
? 段间转移 —— 远转移( far)
? 从当前代码段跳转到另一个
代码段,可以在 1MB范围
? 需要更改 CS段 基值 和 IP偏移
地址
? 目标地址必须用一个 32位数
表达,叫做 32位远指针,它
就是逻辑地址






实际编程时, 汇编程序会根据目标地址的距离,
自动处理成短转移, 近转移或远转移
程序员可用操作符 short,near ptr 或 far ptr 强制
段内直接寻址转移
JMP label ; IP←IP+ 位移量
? 位移量是紧接着 JMP指令后的那条指令的偏移地址,
到目标指令的偏移地址的地址位移
? 当向地址增大方向转移时,位移量为正;向地址减
小方向转移时,位移量为负
实际为相对寻址
jmp again ; 转移到 again处继续执行 ……
again,dec cx ; 标号 again的指令 ……
jmp output ; 转向 output ……
output,mov result,al ; 标号 output的指令
段内间接寻址转移
JMP r16/m16 ; IP←r16/m16
? 将一个 16位寄存器或主存字单元内容送入
IP寄存器,作为新的指令指针,但不修改
CS寄存器的内容
jmp ax ; IP←AX
jmp word ptr [bx] ; IP←[BX]
段间直接寻址转移
JMP far ptr label; IP←label 的偏移地址; CS←label 的段基值
? 将标号所在段的段 基值 作为新的 CS值,
标号在该段内的偏移地址作为新的 IP值;
程序跳转到新的代码段执行
jmp far ptr otherseg; 远转移到代码段 2的 otherseg
段间间接寻址转移
JMP far ptr mem; IP←[mem], CS←[mem+2]
? 用一个双字存储单元表示要跳转的目标地址。
这个目标地址存放在主存中连续的两个字单元
中的,低位字送 IP寄存器,高位字送 CS寄存器
mov word ptr [bx],0
mov word ptr [bx+2],1500h
JMP far ptr [bx] ; 转移到 1500h:0
§ 3.3 80x86的指令系统
? 指令分类
? 功能
? 格式
? 数据传送指令
? 算术运算指令
? 逻辑指令
? 串操作指令
? 程序转移指令
? 处理器控制指令
? 双操作数指令( DEST,SRC)
? 单操作数指令( DEST)
? 无操作数指令(隐含,按约定寻找操作数)
一、数据传送指令
? 数据传送是计算机中最基本、最重要的一
种操作
? 传送指令也是最常使用的一类指令
? 传送指令把数据从一个位置传送到另一个
位置
? 除标志寄存器传送指令外,均不影响标志

? 重点掌握
MOV XCHG XLAT PUSH POP LEA
1,通用数据传送指令
?提供方便灵活的通用传送操作
?有 3条指令
MOV
XCHG
XLAT
1) 传送指令 MOV( move)
? 格式,MOV DEST,SRC
? 功能,将源操作数的内容传送至目的操作数中
即( DEST) ← ( SRC)
? 说明,
? DEST可以是 8/16位的 R( CS,IP除外) /M
? SRC可以是 8/16位的 R/M/立即数
只能出现在源操
作数的位置
1)传送指令 MOV— 立即数传送
MOV reg/mem,imm ; 立即数送寄存器或主存
mov al,4 ;( al) ←4, 字节传送
mov cx,0ffh ;( cx) ←00ffh, 字传送
mov si,200h ;( si) ←0200h, 字传送
mov byte ptr [si],0ah; byte ptr 说明是字节操作
mov word ptr [si+2],0bh; word ptr 说明是字操作
注意立即数是字节量还是字量
明确指令是字节操作还是字操作
1)传送指令 MOV
— 寄存器之间数据传送
MOV reg,reg
mov ax,bx ; (ax) ← (bx), 字传送
mov ah,al ; (ah) ← (al), 字节传送
mov ds,ax ; (ds) ← (ax), 字传送
CS不能做目的操作数
1)传送指令 MOV
— 寄存器与存储器之间数据传送
MOV AL,D_BYTE
MOV DX,[BP] ; DX←SS:[BP]
MOV DL,[SI] ; DL←DS:[SI]
1)传送指令 MOV
— 使用该指令应注意的问题
? SRC与 DEST的长度必须一致
错误示例,MOV AX,BL
MOV CL,3824H
? DEST不能为 CS,IP及立即数
错误示例,MOV VAR1,VAR2
正确实现,MOV AL,VAR2
MOV VAR1,AL
? SRC与 DEST不能同时为存储器操作数 —8086
不支持两个存储单元间数据的直接传送
? SRC与 DEST不能同时为段寄存器
例,DS ← ES
错误,MO DS,ES
正确实现,MO AX,ES
MOV DS,AX
? 不能将立即数直接传送到段寄存器
例,MOV AX,ES
MOV DS,AX
1)传送指令 MOV— 数据传送方向示意
立即数
段寄存器
CS DS ES SS
通用寄存器
AX BX CX DX
BP SP SI DI



2)交换指令 XCHG( exchange)
? 指令格式,XCHG DEST,SRC
? 指令功能,( DEST) ← → ( SRC)
? 寄存器与寄存器之间对换数据
? 寄存器与存储器之间对换数据
注意,不能在存储器与存储器之
间对换数据
2)交换指令 XCHG— 寄存器间交换
例:( ax)=1234h (bx)=5678h 交换 ax
和 bx的内容。
Mov cx,ax
Mov ax,bx
Mov bx,cx 或,
xchg ax,bx ; ax=5678h,bx=1234h
xchg ah,al ; ax=7856h
2)交换指令 XCHG
— 寄存器与存储器交换
xchg ax,ds:[2000h] ; 字交换;等同于 xchg ds:[2000h],ax
xchg al,ds:[2000h] ; 字节交换;等同于 xchg ds:[2000h],al
2)交换指令 XCHG— 例题分析
? 例, (BX)=6F30H,(BP)=0200H,(SI)=0046H,
(SS)=2F00H,(2F246H)=4154H,在指令
XCHG BX,[BP+SI]执行后,相关寄存器和
存储器的内容是什么?
? 分析:源操作数的物理地址 =
(SS) × 16+(BP)+(SI)=
2F000H+0200H+0046H=2F246H
? 指令的功能,(BX) ← → (2F246H)
? 指令执行结果:
(BX)=4154H,(2F246H)=6F30H
3)换码指令 XLAT( translate)
? 指令格式,XLAT
? 指令功能, AL←DS:[BX+AL], 将 BX指定的缓
冲区中,AL指定的位移处的一个字节数据取出
赋给 AL
? 换码指令执行前,
在主存建立一个字节量表格,内含要转换成的目的代码
表格首地址存放于 BX,AL存放相对表格首地址的位移量
? 换码指令执行后,
将 AL寄存器的内容转换为目标代码
mov bx,100h
mov al,03h
xlat
3)换码指令 XLAT— 例题
(BX)
(AL)
DS
数据段
12H
34H
56H
78H
9AH
78H
(AL)=78H
2000
0100
0101
0102
0103 AL←DS:[BX+AL]
2.堆栈操作指令 — 进栈指令 PUSH
? 格式,PUSH SRC
? 功能,SP←SP - 2,
SS:[SP]← ( r16/m16/seg)
例,
push ax
push DS:[2000h]
2.堆栈操作指令 — 出栈指令 POP
? 格式,POP DEST
? 功能,
( r16/m16/seg) ← SS:[SP]
SP←SP+2,
例,
pop DX
pop DS:[2000h]
2.堆栈操作指令 — 应用举例
push ax ; 进入子程序后
push bx
push ds
..,
pop ds ; 返回主程序前
pop bx
pop ax
3,标志寄存器传送指令
?标志寄存器传送指令用来传送标志寄
存器 FLAGS的内容,方便进行对各
个标志位的直接操作
?有 2对 4条指令
? 低 8位传送,LAHF和 SAHF
? 16位传送,PUSHF和 POPF
3,标志寄存器传送指令
— 标志低字节进出 AH指令
格式,LAHF
功能,(AH)←FLAGS 的低
字节
? LAHF指令将标志寄存器
的低字节送寄存器 AH
? SF/ZF/AF/PF/CF状态标
志位分别送入 AH的第
7/6/4/2/0位,而 AH的
第 5/3/1位任意
格式,SAHF
功能,
FLAGS的低字节 ←( AH)
? SAHF将 AH寄存器内容
送 FLAGS的低字节
? 用 AH的第 7/6/4/2/0位
相应设置 SF/ZF/AF/
PF/CF标志
3.标志寄存器传送指令 —
标志寄存器进出堆栈指令
格式,PUSHF
功能,SP←SP -2
SS:[SP]←FLAGS
?PUSHF指令将标志
寄存器的内容压入
堆栈,同时栈顶指
针 SP减 2
格式,POPF
功能,FLAGS←SS:[SP]
SP←SP + 2
?POPF指令将栈顶字单
元内容送标志寄存器,
同时栈顶指针 SP加 2
3.标志寄存器传送指令 —
标志寄存器进出堆栈指令(置位单步标志)
pushf ; 保存全部标志到堆栈
pop ax ; 从堆栈中取出全部标志
or ax,0100h ; 设置 D8=TF=1,ax其它位不变
push ax ; 将 ax压入堆栈
popf ; FLAGS←AX; 将堆栈内容取到标志寄存器
4,地址传送指令
?地址传送指令将存储器单元的逻辑地
址送至指定的寄存器
? 有效地址传送指令 LEA
? 指针传送指令 LDS和 LES
?注意不是获取存储器单元的内容
4,地址传送指令
— 有效地址传送指令 LEA( load EA)
格式,LEA DEST,SRC
16位寄存器
存储器操作数
功能,DEST←SRC 的有效地址 EA
将存储器操作数的有效地址传送至指定的 16
位寄存器中
获得主存单元的有效地址;不是
物理地址, 也不是该单元的内容
可以实现计算功能
LEA BX,BUFR
9A78H
(BX)=9A78H
4,地址传送指令
— 有效地址传送指令 LEA( 例)
23H
093A0H
BUFR
78H
9AH
093AH
DS
093A:0023H
(BX)=0023H
错误!
4,地址传送指令 — 地址 指针
? 存储单元的逻辑地址
段基值( 16位)
段内偏移量( 16位)
? 地址指针( 32位)
M的逻辑地址在 M中需 4
个连续的存储单元
段基值
AD_POINT
XX
XX
偏移量
XX
XX
4,地址传送指令 — 指针传送指令
格式,LDS DEST,SRC
功能,
(DEST)←(SRC )段内偏移量
DS← (SRC+2 ) 段基值
? LDS指令将主存中 SRC
指定的字送至 16位寄存
器 DEST,并将 SRC的下
一字送 DS寄存器
格式,LES DEST,SRC
功能,
(DEST)←(SRC )段内偏移量
ES← (SRC+2 ) 段基值
? LDS指令将主存中 SRC
指定的字送至 16位寄存
器 DEST,并将 SRC的下
一字送 ES寄存器
? 例, (DS)=B000H,
(BX)=080AH,
(0B080AH)=05AEH,
(0B80CH)=4000H,
(405AEH)=9634H,在
执行指令
LDS DI,[BX]
MOV AX,[DI]
后,(AX)=?
BX=080AH
B0000H
0B80AH
40000H
34H
96H
AEH
05H
00H
40H
405AEH
05AEH
0B80EH
(DI)=05AEH
(DS)=4000H
? 结果,
(DS)=4000H
(DI)=05AEH
(AX)=9634H
3.加 /减 1指令
? 格式,INC DEST
DEC DEST
? 功能,(DEST) ← (DEST)+/-1
? 受影响标志,PF,AF,ZF,SF,OF
? 说明,
? DEST可以是字节或字 R,M
? 功能与 ADD/SUB相似,但占用字节少,且不影响标
志位 CF 。常用于修改地址指针及循环计数器。
4.求补指令(求负数)
? 格式,NEG DEST
? 功能,(DEST) ←0 -(DEST)
? 受影响标志,CF,PF,AF,ZF,SF,OF
? 说明,
? DEST可以是字节或字 R,M
? 操作对象是有符号的数
? 当操作数取最小值( -128或 -32768)时,执行该指令
后,操作数无变化,OF=1
? 当操作数为 0时,结果为 0,但 CF=0,其他情况 CF=1
4.求补指令 (举例)
例,AL=13H,执行指

NEG AL
后 AL的值
1
0000 0000
0001 0011
1110 1101

AL
AL=-13H
1001 0010
0000 0001
1001 0011
+
5.比较指令 CMP( compare)
? 格式,CMP DEST,SRC
? 功能,(DEST) -(SRC)
? 受影响标志,CF,PF,AF,ZF,SF,OF
? 说明,
? DEST,SRC可以是字节或字 R,M,长度必须一致
? SRC还可以是 imm
? DEST和 SRC不能同时为 M
? 该指令主要用于比较两数的关系
5.比较指令 CMP— 应用
? ZF=1 ;两数相等
? 两个无符号数比较
CMP AX,BX ;
0 AX≥ BX
1 AX < BX
CF=
? 两个带符号的数的比较不能用单一的符号
判断两个数的关系
指令执行后 SF与 OF相同,(DEST)>SRC SF与 OF不同,(DEST)<SRC
5.比较指令 CMP— (CMP AL,BL)
AL=-2
BL=127
1111 1110
0111 1111
0111 1111
-
SF=0
OF=1 相异,AL<BL
AL=-2
BL=-1
1
1111 1110
1111 1111
1111 1111
-
SF=1
OF=0 相异,AL<BL
5.比较指令 CMP— (CMP AL,BL)
AL=-1
BL=-2
1111 1111
1111 1110
0000 0001
-
SF=0
OF=0 相同,AL>BL
AL=127
BL=-2
1
0111 1111
1111 1110
1000 0001
-
SF=1
OF=1 相同,AL>BL
6.乘法指令
MUL r8/m8;无符号字节乘法; AX←AL × r8/m8
MUL r16/m16;无符号字乘法; DX.AX←AX × r16/m16
IMUL r8/m8;有符号字节乘法; AX←AL × r8/m8
IMUL r16/m16;有符号字乘法; DX.AX←AX × r16/m16
6.乘法指令 — 功能
? 乘法指令分无符号和有符号乘法指令
? 乘法指令的源操作数显式给出,隐含使用
另一个操作数 AX和 DX
? 字节相乘,AL与 r8/m8相乘,得到 16位的结
果,存入 AX
? 字相乘,AX与 r16/m16相乘,得到 32位的结
果,其高字存入 DX,低字存入 AX
? 乘法指令利用 OF和 CF判断乘积的高一半
是否具有有效数值
6.乘法指令 — 对标志的影响
乘法指令如下影响 OF和 CF标志,
? MUL指令 —— 若乘积的高一半( AH或
DX)为 0,则 OF=CF=0;否则
OF=CF=1
? IMUL指令 —— 若乘积的高一半是低一
半的符号扩展,则 OF=CF=0;否则均
为 1
6.乘法指令 — (例)
mov al,0b4h ; al=b4h=180
mov bl,11h ; bl=11h=17
mul bl ; ax=Obf4h=3060,OF=CF=1,AX高 8位不为 0
mov al,0b4h ; al=b4h=- 76
mov bl,11h ; bl=11h=17
imul bl ; ax=faf4h=- 1292,OF=CF=1,AX高 8位有效
6.除法指令
DIV r8/m8 ;无符号字节除法
AL←AX ÷ r8/m8的商,Ah←AX ÷ r8/m8的余数
DIV r16/m16 ;无符号字除法; AX←DX.AX ÷ r16/m16的商,DX←DX.AX ÷ r16/m16的余

IDIV r8/m8 ;有符号字节除法,
AL←AX ÷ r8/m8的商,Ah←AX ÷ r8/m8的余数
IDIV r16/m16 ;有符号字除法,; AX←DX.AX ÷ r16/m16的商,DX←DX.AX ÷ r16/m16的余数
6.除法指令 — 功能
? 除法指令分无符号和有符号除法指令
? 除法指令的除数显式给出,隐含使用另一
个操作数 AX和 DX作为被除数
? 字节量除法,AX除以 r8/m8,8位商存入 AL,
8位余数存入 AH
? 字量除法,DX.AX除以 r16/m16,16位商存入
AX,16位余数存入 DX
? 除法指令对标志没有影响
? 除法指令会产生结果溢出
6.除法指令 — 除法错中断
? 当被除数远大于除数时,所得的商就有可
能超出它所能表达的范围。如果存放商的
寄存器 AL/AX不能表达,便产生溢出,
8086CPU中就产生编号为 0的内部中断 ——
除法错中断
? 对 DIV指令,除数为 0,或者在字节除时商超过
8位,或者在字除时商超过 16位,则发生除法
溢出
? 对 IDIV指令,除数为 0,或者在字节除时商不
在 -128~ 127范围内,或者在字除时商不在 -
32768~ 32767范围内,则发生除法溢
6.除法指令 — (例)
mov ax,0400h ; ax=400h=1024
mov bl,0b4h ; bl=b4h=180
div bl ;商 al= 05h= 5,余数 ah= 7ch= 124
mov ax,0400h ; ax=400h=1024
mov bl,0b4h ; bl=b4h=- 76
idiv bl ;商 al= f3h=- 13,余数 ah= 24h= 36
7.符号扩展指令 — 符号扩展的概念
? 符号扩展是指用一个操作数的符号位(即最
高位)形成另一个操作数,后一个操作数的
各位是全 0(正数)或全 1(负数)。 符号扩
展不改变数据大小
? 对于数据 64H(表示数据 100),其最高位 D7为
0,符号扩展后高 8位都是 0,成为 0064H(仍表
示数据 100)
? 对于数据 ff00H(表示有符号数- 256),其最
高位 D15为 1,符号扩展后高 16位都是 1,成为
ffffff00H(仍表示有符号数- 256)
7.符号扩展指令
CBW ; AL的符号扩展至 AH;如 AL的最高有效位是 0,则 AH= 00; AL的最高有效位为 1,则 AH= FFH。 AL不变
CWD ; AX的符号扩展至 DX;如 AX的最高有效位是 0,则 DX= 00; AX的最高有效位为 1,则 DX= FFFFH。 AX不变
?符号扩展指令常用于获得双倍长的数据
7.符号扩展指令 — (例,AX/BX)
cwd ; DX.AX←AX
idiv bx ; AX←DX.AX ÷ BX
利用符号扩展指令得到除法指令所需要的
倍长于除数的被除数
对无符号数除法应该采用直接使高 8位或
高 16位清 0的方法, 获得倍长的被除数
8.十进制调整指令
? 十进制数调整指令对二进制运算的结果
进行十进制调整,以得到十进制的运算
结果
? 分成压缩 BCD码和非压缩 BCD码调整
8.十进制调整指令
— 压缩 BCD码加、减调整指令
( ADD AL,i8/r8/m8)
( ADC AL,i8/r8/m8)
DAA; AL← 将 AL的加和调整
为压缩 BCD码
( SUB AL,i8/r8/m8)
( SBB AL,i8/r8/m8)
DAS; AL← 将 AL的减差调整为压
缩 BCD码
?使用 DAA或 DAS指令前,应先执行以 AL为目的操作
数的加法或减法指令
?DAA和 DAS指令对 OF标志无影响,按结果影响其他
标志
8.十进制调整指令 —
压缩 BCD码加、减调整指令(例)
mov al,68h ; al=68h,压缩 BCD码表示真值 68
mov bl,28h ; bl=28h,压缩 BCD码表示真值 28
add al,bl ;二进制加法,al=68h+28h=90h
daa ;十进制调整,al=96h;实现压缩 BCD码加法,68+ 28= 96
mov al,68h ; al=68h,压缩 BCD码表示真值 68
mov bl,28h ; bl=28h,压缩 BCD码表示真值 28
sub al,bl ;二进制减法,al=68h-28h=40h
das ;十进制调整,al=40h;实现压缩 BCD码加法,68-28= 40
8.十进制调整指令
— 非压缩 BCD码加、减调整指令
( ADD AL,i8/r8/m8)
( ADC AL,i8/r8/m8)
AAA; AL← 将 AL的加和调整
为非压缩 BCD码; AH←AH +调整的进位
( SUB AL,i8/r8/m8)
( SBB AL,i8/r8/m8)
AAS; AL← 将 AL的减差调整为
非压缩 BCD码; AH←AH -调整的借位
?使用 AAA或 AAS指令前,应先执行以 AL为目的操作数的加
法或减法指令
?AAA和 AAS指令在调整中产生了进位或借位,则 AH要加上
进位或减去借位,同时 CF=AF=1,否则 CF=AF=0;它们对
其他标志无影响
8.十进制调整指令
— 非压缩 BCD码加、减调整指令(例)
mov ax,0608h ; ax=0608h,非压缩 BCD码表示真值 68
mov bl,09h ; bl=09h,非压缩 BCD码表示真值 9
add al,bl ;二进制加法,al=08h+09h=11h
aaa ;十进制调整,ax=0707h;实现非压缩 BCD码加法,68+ 9= 77
mov ax,0608h ; ax=0608h,非压缩 BCD码表示真值 68
mov bl,09h ; bl=09h,非压缩 BCD码表示真值 9
sub al,bl ;二进制减法,al=08h-09h=ffh
aas ;十进制调整,ax=0509h;实现非压缩 BCD码减法,68-9= 59
例:用乘法指令实现 32位二进制数
的相乘
c d
a b
ax
dx ax
dx
dx ax
dx ax
×
+
b× d
a× d
b× c
a× c
DSEG SEGMENT PARA 'Data‘
num1 dw 1220h,48a2h
num2 dw 2398h,0ae41h
produ dw 4 dup(0)
DSEG ENDS
a b
c d
num1 num1+2
num2 num2+2
produ produ+2 produ+4 produ+6
三、逻辑指令
(逻辑 )位操作类指令以二进制位为基本单
位进行数据的操作;这是一类常用的指
令,都应该特别掌握
? 逻辑运算指令
? 测试指令
? 移位指令
1.逻辑运算指令
? 格式,AND DEST,SRC
OR DEST,SRC
XOR DEST,SRC
NOT DEST ? 功能,(DEST) ← (DEST) (SRC) ∧ ∨

(DEST) ← (DEST)
受影响标志,CF=0,OF=0,PF,ZF,SF,NOT对标志无影响
1.逻辑运算指令 — 应用
mov al,45h ;逻辑与 al=01h
and al,31h ; CF=OF=0,SF=0,ZF=0,PF=0
mov al,45h ;逻辑或 al=75h
or al,31h ; CF=OF=0,SF=0,ZF=0,PF=0
mov al,45h ;逻辑异或 al=74h
xor al,31h ; CF=OF=0,SF=0,ZF=0,PF=1
mov al,45h ;逻辑非 al=0bah
not al ;标志不变
1.逻辑运算指令 — 应用
? AND指令可用于复位某些位(同 0相与),不影响其他位:
将 BL中 D3和 D0位清 0,其他位不变
AND BL,11110110B
? OR指令可用于置位某些位(同 1相或),不影响其他位:
将 BL中 D3和 D0位置 1,其他位不变
OR BL,00001001B
? XOR指令可用于求反某些位(同 1相异或),不影响其他
位:将 BL中 D3和 D0位求反,其他不变
XOR BL,00001001B
XOR AX,AX ;AX=0,CF=ZF=0
XOR AL,43H ;ZF=0则 AL≠ 43H;ZF=1AL=43H则
2.测试指令 TEST
? 格式,TEST DEST,SRC
? 功能,将两个操作数进行逻辑“与”
运算,结果只反映在标志位上,对操作
数无影响
? 受影响标志,CF=0,OF=0,PF,ZF,SF
? 说明:该指令用于测试操作数的某位是
否为 1,被测试的位与 1相“与”
TEST AL,01H ;测试 D0的值 ZF=0,D0=1 ZF=1,D
0=0
3.移位指令
?逻辑移位指令
?算术移位指令
?循环移位指令
1)逻辑移位指令
? 格式,SHL DEST,CNT
SHR DEST,CNT
? 功能,将 DEST按 CNT 指定的次数左 /右移位,
移出的位 → CF,空出的位补 0,结果 → DEST
? 受影响标志,OF ( CNT=1时 ),CF,PF,ZF,SF
? 说明,
? DEST 可以是字节或字 R,M
? CNT为 1或 CL
? 只在 CNT=1时。 CF与 SF相同,OF=0; CF与 SF不同,
OF=1。
? 该指令可用于无符号数 ÷ /× 2的操作
逻辑左移 SHL AL,1
2)算术移位指令
? 格式,SAL DEST,CNT
SAR DEST,CNT
? 功能,
? SAL与 SHL完全相同
? SAR每右移 1位,最低位 → CF,最高位保持不变(用
于带符号数的除法),结果 → DEST
? 受影响标志,OF ( CNT=1时 ),CF,PF,ZF,SF
? 说明,
? DEST 可以是字节或字 R,M
? CNT为 1或 CL
逻辑移位指令的功

移位指令应用举例
MOV CL,4
MOV AL,0F0H ; AL=F0H
SHL AL,1 ; AL=E0H; CF=1,SF=1,ZF=0,PF=0,OF=0
SHR AL,1 ; AL=70H; CF=0,SF=0,ZF=0,PF=0,OF=1
SAR AL,CL ; AL=03H; CF=1,SF=0,ZF=0,PF=1
SAR AL,1 ; AL=38H; CF=0,SF=0,ZF=0,PF=0,OF=0
mov si,ax
shl si,1 ; si←2 × ax
add si,ax ; si←3 × ax
mov dx,bx
mov cl,03h
shl dx,cl ; dx←8 × bx
sub dx,bx ; dx←7 × bx
add dx,si ; dx←7 × bx+ 3× ax
移位指令应用举例
3)循环移位指令
? 格式,ROL DEST,CNT
ROR DEST,CNT
RCL DEST,CNT
RCR DEST,CNT ?功能,小循环, 将 DEST按 CNT 指定的次数左 /右移位,移出的位同时送 CF和空出的位
大循环, 将 DEST按 CNT 指定的次数左 /右移
位,CF → 空出的位,移出的位 → CF
?受影响标志,OF ( CNT=1时 ),CF
?说明:用大循环可完成多字节的移位操作
小循环
大循环
不带进位循环移位指令(小循环)
带进位循环移位指令(大循环)
循环移位指令
— 将 DX.AX中 32位数值左移一位
SHL AX,1
RCL DX,1
DX
AX CF
0
循环移位指令 — 位传送;把 AL最低位送 BL最低位,保持 AL不变
ROR AL,1
RCL BL,1
ROL AL,1
AL CF
BL
CF
AL
CF
AL之 D0
循环移位指令 — BCD码合并; AH.AL分别存放着非压缩 BCD码的两
位;将它们合并成为一个压缩 BCD码存 AL
AND AX,0F0FH ;保证高 4位为 0
MOV CL,4
ROL AH,CL ;也可以用 SHL AH,CL
ADD AL,AH ;也可以用 OR AL,AH
四、串操作指令
? 串操作指令是 8086指令系统中比较独特的一
类指令,采用比较特殊的数据串寻址方式,
在操作主存连续区域的数据时,特别好用、
因而常用
? 串操作指令的操作数是 主存中连续存放的数
据串( String) —— 即在连续的主存区域中,
字节或字的序列
? 串操作指令的 操作对象是以字( W)为单位
的字串,或是以字节( B)为单位的字节串
四、串操作指令 —串寻址方式
? 源操作数用寄存器 SI寻址,默认在数据段 DS中,但
允许段超越,DS:[SI]
? 目的操作数用寄存器 DI寻址,默认在附加段 ES中,
不允许段超越,ES:[DI]
? 每执行一次串操作指令,SI和 DI将自动修改,
? ± 1(对于字节串)或 ± 2(对于字串)
? 执行指令 CLD指令后,DF = 0,地址指针增 1或 2
? 执行指令 STD指令后,DF = 1,地址指针减 1或 2
1.串传送 MOVS( move string)
? 把字节或字操作数从主存的源地址传
送至目的地址
MOVSB;字节串传送,ES:[DI]←DS:[SI]; SI←SI ± 1,DI←DI ± 1
MOVSW;字串传送,ES:[DI]←DS:[SI]; SI←SI ± 2,DI←DI ± 2
串传送 MOVSB (正向 DF= 0 )
串传送 MOVSW(反向 DF= 1)
1.串传送 MOVS— 字节串传送(例)
mov si,offset source
mov di,offset destination
mov cx,100 ; cx← 传送次数
cld ;置 DF=0,地址增加
again,
movsb ;传送一个字节
dec cx ;传送次数减 1
jnz again ;判断传送次数 cx是否为 0;不为 0,则到 again位置执行指令;否则,结束
2.串存储 STOS( store string)
? 把 AL或 AX数据传送至目的地址
STOSB;字节串存储,ES:[DI]←AL; DI←DI ± 1
STOSW;字串存储,ES:[DI]←AX; DI←DI ± 2
2.串存储 — 串存储(例)
mov ax,0
mov di,0
mov cx,8000h ; cx← 传送次数( 32× 1024)
cld ; DF=0,地址增加
again,
stosw ;传送一个字
dec cx ;传送次数减 1
jnz again ;传送次数 cx是否为 0
3.串读取 LODS( load string)
? 把指定主存单元的数据传送给 AL或 AX
LODSB;字节串读取,AL←DS:[SI]; SI←SI ± 1
LODSW;字串读取,AX←DS:[SI]; SI←SI ± 2
mov si,offset block
mov di,offset dplus
mov bx,offset dminus
mov ax,ds
mov es,ax ;数据都在一个段中,所以设置 es=ds
mov cx,count ; cx← 字节数
cld
go_on:lodsb ;从 block取出一个数据
test al,80h ;检测符号位,判断是正是负
jnz minus ;符号位为 1,是负数,转向 minus
stosb ;符号位为 0,是正数,存入 dplus
jmp again ;程序转移到 again处继续执行
minus:xchg bx,di
stosb ;把负数存入 dminus
xchg bx,di
again:loop go_on ;字节数减 1
4.串比较 CMPS( compare string)
? 将主存中的源操作数减去至目的操作数,以便
设置标志 (ZF),进而比较两操作数之间的关系
CMPSB;字节串比较,DS:[SI]- ES:[DI]; SI←SI ± 1,DI←DI ± 1
CMPSW;字串比较,DS:[SI]- ES:[DI]; SI←SI ± 2,DI←DI ± 2
4.串比较 CMPS(例)
mov si,offset string1
mov di,offset string2
mov cx,count
cld
mov al,0ffh ;标记初始为不同
again:cmpsb ;比较两个字符
jnz output ;有不同字符,转移
dec cx
jnz again ;进行下一个字符比较
mov al,0 ;字符串相等,设置 00h
output:mov result,al ;输出结果标记
5.串扫描 SCAS( scan string)
? 将 AL/AX减去至目的操作数,以便设置标志
(ZF),进而比较 AL/AX与操作数之间的关系
SCASB;字节串扫描,AL- ES:[DI]; DI←DI ± 1
SCASW;字串扫描,AX- ES:[DI]; DI←DI ± 2
5.串扫描 SCAS— (例)
mov di,offset string
mov al,20h
mov cx,count
cld
again:scasb ;搜索
jz found ;为 0( ZF=1),发现空格
dec cx ;不是空格
jnz again ;搜索下一个字符
,.,;不含空格,则继续执行
found,..,
重复前缀指令 ( repeat)
? 串操作指令执行一次,仅对数据串中的一个
字节或字量进行操作。但是串操作指令前,
都可以加一个重复前缀,实现串操作的重复
执行。重复次数隐含在 CX寄存器中
? 重复前缀分 2类,3条指令,
? 配合不影响标志的 MOVS,STOS(和 LODS)指
令的 REP前缀
? 配合影响标志的 CMPS和 SCAS指令的 REPZ和
REPNZ前缀
REP重复前缀指令
REP ;每执行一次串指令,CX减 1;直到 CX= 0,重复执行结束
?REP前缀可以理解为:当数据串没有结束
( CX≠0),则继续传送
?例 2中,程序段的最后 3条指令,可以分别替换
为,
REP MOVSB 和 REP STOSW
REP重复前缀指令
— 字节串传送(例)
mov si,offset source
mov di,offset destination
mov cx,100 ; cx← 传送次数
cld ;置 DF=0,地址增加
again,
movsb ;传送一个字节
dec cx ;传送次数减 1
jnz again ;判断传送次数 cx是否为 0;不为 0,则到 again位置执行指令;否则,结束
rep movsb
REPZ/REPNZ重复前缀指令
REPZ ;每执行一次串指令,CX减 1;并判断 ZF是否为 0,;只要 CX= 0或 ZF= 0,重复执行结束
REPNZ ;每执行一次串指令,CX减 1;并判断 ZF是否为 1,;只要 CX= 0或 ZF= 1,重复执行结束
当数据串没有结束( CX≠0),并且串相等
( ZF= 1),则继续串操作
当数据串没有结束( CX≠0),并且串不相等
( ZF= 0),则继续串操作
mov si,offset string1
mov di,offset string2
mov cx,count
cld
mov al,0ffh ;标记初始为不同
again:cmpsb ;比较两个字符
jnz output ;有不同字符,转移
dec cx
jnz again ;进行下一个字符比较
mov al,0 ;字符串相等,设置 00h
output:mov result,al ;输出结果标记
REPZ/REPNZ重复前缀指令
— 串比较 CMPS(例)
repz cm sb
jnz output
REPZ/REPNZ重复前缀指令
— 串扫描(例)
mov di,offset string mov al,20h
mov cx,count
cld
again:scasb ;搜索
jz found ;为 0( ZF=1),发现空格
dec cx ;不是空格
jnz again ;搜索下一个字符
,.,;不含空格,则继续执行
found,..,
repnz scasb
jz found
例:在 STRBUF字符串中寻找 STRING
中指定的二字符出现的个数
DSEG SEGMENT PARA 'Data'
STRBUF DB 'ASASAASASSASSAASASAS'
COUNT EQU $-STRBUF
STRING DB 'AS'
MESSG DB "THE NUMBER OF 'AS' IS, "
NUM DB?
DB 0AH,0DH,'$‘
DSEG ENDS
例:在 STRBUF字符串中寻找 STRING
中指定的二字符出现的个数
? 采用逐个比较的方法
? 因目的串为 2个字符,故使用 CMPSW
? 应注意的问题,
? 若某次比较不同时,SI?SI+2,但有可能出现
‘ AAS’的情况,应做 SI?SI-1的处理
? 执行 CMPSW亦做 DI ?DI+2,而目的串应始终
指向 STR,故 DI ?DI-2
? 比较相同时,循环计数器 -2
SI ?源串首地址 STRBUF
DI ?目的串首地址 STRING
CX ?源串长度 -1
方向标志 DF ?0
计数器 BL ?0
CMPSW
ZF=1
BL ?BL+1
CX ?CX-1
DI ? DI-2
CX ?CX-1
CX=0
(NUM) ?BL
SI?SI-1
Y
Y
N
N
LOP
NEXT1
NEXT
LEA SI,STRBUF
LEA DI,STRING
MOV CX,COUNT-1
CLD
MOV BL,0
LOP,CMPSW
JNZ NEXT1
INC BL
DEC CX
JMP NEXT
NEXT1,DEC SI
NEXT,DEC DI
DEC DI
CMP CX,0 ;防止 CX已为 0,仍使其继续进行 -1操作的情况
JZ OUTPUT
LOOP LOP
OUTPUT,ADD BL,30H
MOV NUM,BL
MOV AH,9
LEA DX,MESSG
INT 21H
五、控制转移指令
六、处理器控制指令
?标志位操作指令
?其他处理器控制指令
1.标志位操作指令
DF
CLD ; DF ← 0
STD ; DF ← 1
IF
CLI ; IF ← 0
STI ; IF ← 1
CF
CLC ; CF ← 0
STC ; CF ← 1
CMC ; CF ← CF
不影响其他标志位
其他处理器控制指令
— 空操作
? 格式,NOP
? 功能:完成一次空操作,除使 IP ← IP+1
外不做任何操作。占用 CPU3个时钟周期,
在程序中可做少量延时调整。
其他处理器控制指令
— 停机指令
? 格式,HLT
? 功能:使 CPU暂停工作,处于等待状态,
等待外部中断到来以结束停机状态,继续
下面指令的执行。
? 该指令对标志位无影响
其他处理器控制指令
— 等待指令
? 格式,WAIT
? 功能:使 CPU处于等待状态,等待协处理
器完成当前的工作。
其他处理器控制指令
— 换码(处理器交权)指令
? 格式,ESC 6位 imm,R/M
? 功能,浮 点协处理器 8087指令是与 8086的整数指令
组合在一起的,当 8086发现是一条浮点指令时,就
利用 ESC指令将浮点指令交给 8087执行
? 实际编写程序时,一般采用易于理解的浮点指令助
记符格式
ESC 6,[SI];实数除法指令,FDIV dword ptr [SI]
ESC 20H,AL;整数加法指令,FADD ST(0),ST
其他处理器控制指令
— 总线封锁前缀 LOCK
? 功能:与其他指令联合以维持总线的封锁
信号直到与其联合的控制指令执行完成。
? 用于保证指令的完整执行。
§ 3.4 80x86的机器语言指令概况
? 介绍指令编码是为了说明 CPU指令系统的
机器码是如何构成的
双操作数指令编码格式 2-6字节组成
单操作数指令编码格式
与 AX,AL有关的指令编码格式
其它指令编码格式
一,双操作数指令编码格式
? MOV ADD SUB AND
data_low data_high D_high D_low op code
7 0
d w MOD REG R/M
7 0 7 0 7 0 210 543 76 7 2 1 0
操作特征 寻址特征 位移量 立即数
1,操作特征部分
1) 操作码字段,说明指令规定的操作种类和操
作数的来源(是否使用 AX\AL或 imm)
2) 方向字段,表示操作数由寻址特征的哪部分表

1 DEST 由 REG字段确定,SRC由 MOD和 R/M确定
0 DEST 由 MOD和 R/M 字段确定,SRC由 REG确定 d=
R或 M 3) w字段,
1 字操作
0 字节操作 w=
2,寻址特征部分
表示两个操作数所使用的寻址方式 1) REG D5D4D3 共 3位,8种组合具体确定哪个 R
REG w=1 w=0
000 AX AL
001 CX CL
010 DX DL
011 BX BL
100 SP AH
101 BP CH
110 SI DH
111 DI BH
2,寻址特征部分
2) MOD(寻址方式)字段, D7D6共 2位
3) R/M字段, D2D1D0共 3位
2) 3) 共同确定 1个操作数 R/M
直接
R间址
基址、变址
基址加变址
MOD
R/M
EA的计算公式 11
00 01 10 w=0 W=1
000 ( BX+SI)
DS
( BX+SI) +D8
DS
( BX+SI ) +D16
DS
AL AX
001 ( BX+DI)
DS
( BX+DI)+D8
DS
( BX+DI)+D16
DS
CL CX
010 ( BP+SI )
SS
( BP+SI ) +D8
SS
( BP+SI )+D16
SS
DL DX
011 ( BP+DI )
SS
( BP+DI ) +D8
SS
( BP+DI ) +D16
SS
BL BX
100 ( SI )
DS
(SI) +D8
DS
(SI) +D16
DS
AH SP
101 (DI)
DS
(DI) +D8
DS
(DI) +D16
DS
CH BP
110 D16
DS
(BP) +D8
SS
(BP) + D16
SS
DH SI
111 (BX)
DS
(BX) +D8
DS
(BX) + D16
DS
BH DI
3,位移量部分
由寻址特征决定了是否包含该部分
MOD=11/00,不包含该部分
MOD=01,第 3字节
MOD=10,第 3,4字节
4,立即数部分
如有立即数则位于指令的最后两字节
如有段超越时,在指令编码前加 1字节
二,指令的执行时间
取指
取操作数
执行指令
传送结果
各阶段所需时间的总和
指令 寻址方式 时钟周期
加法 ADD R-R 3
传送 MOV R-R 2
整数乘法 IMUL R16 128-154
整数除法 IDIV R16 165-184
移位 R,1 2
转移 JMP 直接 15
条件转移 不转移 4
转移 16
不仅不同指令的执行时间差别很大,而且同一种指令
使用不同的寻址方式执行时间的差别也很大。
三、段定义伪操作 — 完整段定义伪指令
段名 SEGMENT 定位 组合 段字 '类别 '
…… ;语句序列
段名 ENDS
? 段定义由 SEGMENT和 ENDS这一对伪指令实现,
SEGMENT伪指令定义一个逻辑段的开始, ENDS伪
指令表示一个段的结束
? 段定义指令后的 4个关键字用于确定段的各种属
性, 堆栈段要采用 stack组合类型
? 如果不指定, 则采用默认参数;但如果指定,
注意要按照上列次序
三、段定义伪操作
— 段定位( align) 属性
? 表示对逻辑段起始边界的选择,可为,
PAGE 段从一个页边界开始
( XXX00H,256Bytes/Page)
PARA 段节边界开始( XXXX0H)
DWORD 段从一个 4倍数地址开始
WORD 段从一个偶地址开始
BYTE 段可以从任意单元开始
? 完整段定义伪指令的默认定位属性是 PARA
三、段定义伪操作
— 段组合( combine) 属性
STACK 把所有的同类别段连接在一起,段基
值 →SS,且自动为 SP初始化。在一个程序中一般
应该有一个堆栈段。
AT 表达式 表示本段定位在表达式所指示的节的边
界上
AT 0930H 表示本段的物理地址从 09300H开始
MEMORY 表示本段定位在所有其它段的最高地

三、段定义伪操作
— 段组合( combine) 属性
? 指定多个逻辑段之间如何连接与定位,可为,
PRIVATE 本段与其他段没有连接关系,这是
完整段定义伪指令默认的段组合方式
PUBLIC 在满足定位关系的前提下,连接程序把
本段与所有同名段相邻地连接在一起,形成新的逻
辑段。(可在程序的不同位置及不同的文件中使用
段定义语句定义一个逻辑段)
COMMON 产生一覆盖段,两个同名段起始地
址相同,用较长的段覆盖较短的段
三、段定义伪操作
— 段类别( class) 属性
? 当连接程序组织段时,将所有的同类别段
相邻分配
? 段类别可以是任意名称,但必须位于单引
号中
? 大多数 MASM程序使用 'code','data'和
'stack’来分别指名代码段、数据段和堆栈
段,以保持所有代码和数据的连续
名字项-标号、变量
标号的命名:根据用途,由字母、数字、专用符号?,.,-
, $,@
约定,
? 最长 31个字符
? 第一个字符不能是数字
?? - $@可出现在标号的任意位置,但? $不能单独使

?, 只能出现在起始位置
? 一个程序中,每个标识符的定义是唯一的,且不能
与任何保留字相同
汇编语言程序格式
? 【 名字项 】 操作项 操作数 【 ;注释项 】
标号 指令
变量 伪指令
标号
? 指令的符号地址
? 段属性( SEG)
? 偏移量属性( OFFSET)
? 类型属性( Distance类型):表示标号的转移特性
类型,
NEAR:本标号只能被标号所在段的指令访问(段内转
移、调用)
FAR:可被其他段的指令访问(段间调用、转移 )
变量
? 段属性( SEG)
? 偏移量属性( OFFSET)
? 类型属性( Distance类型):变量所占的
字节数。
操作数
? 指令中的操作数可以以表达式的形式出现
常数
变量
标号
通过操作运算符连接而成 表达式
? 汇编程序在汇编过程中计算表达式,最终得到一
个数值
? 程序运行之前,就已经计算出了表达式;所以,
程序运行速度没有变慢,但增强程序的可读性
运算符
1,算术操作(运算)符
2,逻辑操作(运算)符
3,关系操作(运算)符
4,数值返回操作(运算)符
5,属性修改操作(运算)符
运算符
运算符 — 算术运算符
? + - * / MOD 实现加、减、乘、除、
取模、移位的运算
MOV AX,3*4+5;等价于 MOV AX,17
? 其中 MOD也称为取模,它产生除法之后的
余数,如 19 mod 7 = 5
? 加 +和减 -运算符还可以用于地址表达式
算术运算符 — 例
ary dw 1,2,3,4,5
ary_end dw?
计算 ary的元素个数放 ax
mov ax,(ary_end-ary)/2
运算符 — 逻辑与移位运算符
? AND OR XOR NOT SHR SLR
? 实现按位相与、相或、异或、求反,左移,
右移的逻辑运算
OR AL,03H AND 45H 0R AL,01H
MOV AX,NOT 0F0H MOV AX,0FF0FH
MOV BL,55H AND 0F0H MOV BL,50H
运算符 — 关系运算符
? EQ NE GT LT GE LE
? 用于比较和测试符号数值
? 表达式 1 关系运算符 表达式 2
? 表达式为常数时,按无符号数进行比较
? 表达式为变量(同段内)时,比较其偏移量
? MASM用 0FFH/0FFFFH( 补码 -1)表示条件为真
? MASM用 0000H表示条件为假
运算符 — 关系运算符(举例)
MOV AX,0FH EQ 1111B ←→ MOV AX,0FFFFH
MOV BX,0FH NE 1111B ←→ MOV BX,0
VAR DW NUM LT 0ABH;当已定义的常数 NUM小于 ABH时,则 VAR ← 0FFH
X EQU 5
MOV BX,((X GT 10) AND 100)OR((X LT 10) AND 50)
运算符 — 数值返回运算符
? 操作对象:存储器操作数(变量 /标号)
? 格式,运算符 变量名 /标号名
1,SEG 名字 /标号
返回名字或标号的段基值
MOV AX,SEG K1
2,OFFSET 名字 /标号
返回名字或标号的段内偏移地址
MOV SI,OFFSET VAR
运算符 — 数值返回运算符
3,TYPE 名字 /标号
返回名字或标号的类型属性,以数字形式表示
类型属性 数字形式
变量
BYTE 1
WORD 2
DWORD 4
标号 NEAR -1 FAR -2
运算符 — 数值返回运算符(例)
V1 DB ‘ABCD’
V2 DW 1234H,5678H
V3 DD V2
……
MOV AL,TYPE V1 ;AL=1
MOV CL,TYPE V2 ;CL=2
MOV CH,TYPE V3 ;CH=4
运算符 — 数值返回运算符
4,LENGTH 名字 /标号
只用于变量,且为 DUP所定义
如未用 DUP定义则返回值为 1
如使用 DUP定义则返回最外层之值
运算符 — 数值返回运算符(例)
K1 DB 10H DUP(0)
K2 DB 10H,20H,30H
K3 DW 20H DUP(0,1,2 DUP(2))
K4 DB ‘ABCD’
……
MOV AL,LENGTH K1 ;AL=10H
MOV BL,LENGTH K2 ;BL=1
MOV CX,LENGTH K3 ;CX=20H
MOV DX,LENGTH K4 ;DX=1
运算符 — 数值返回运算符
5,SIZE 名字
只用于变量,得到重复定义的变量的数组元
素所占字节数 =LENGTH*TYPE
K1 DB 10H DUP(0)
K2 DB 10H,20H,30H
K3 DW 20H DUP(0,1,2 DUP(2))
K4 DB ‘ABCD’
……
MOV AL,LENGTH K1 ;AL=10H
MOV BL,LENGTH K2 ;BL=1
MOV CX,LENGTH K3 ;CX=20H
MOV DX,LENGTH K4 ;DX=1
MOV AL,SIZE K1 ;AL=10H
MOV BL,SIZE K2 ;BL=1
MOV CL,SIZE K3 ;CL=40H
MOV DL,SIZE K4 ;DL=1
运算符 — 属性修改运算符
? 对存储器操作数(名字 /标号)的属性进
行修改
1,PTR 运算符
类型 PTR 地址表达式
该修改是临时的,只在当前语句有效
标号, NEAR/FAR
变量,BYTE/WORD /DWORD
标号名
作为地址指针的 R
变量名
运算符 — 属性修改运算符(例)
DA_BYTE DB 20H DUP(0)
DA_WORD DW 30H DUP(0)
……
LEA BX DA_WORD
LEA SI,DA_BYTE
MOV AX,WORD PTR DA_BYTE[10H]
ADD BYTE PTR DA_WORD[20H],BL
INC BYTE PTR [BX]
SUB WORD PTR [SI],30H
AND AX,WORD PTR [BX][SI]
运算符 — THIS运算符
? THIS 类型名
? 利用 THIS说明的操作数具有汇编时的当前逻辑
地址,但具有指定的类型
? LABEL伪指令的功能等同于,EQU THIS”
D_BYTE EQU THIS BYTE
W_WORD DW 20H DUP(0);定义 20H字单元,该区域可按字节访问,也可以
按字访问
运算符 — HIGH/LOW运算符
? 操作对象:常数 /地址表达式
? 功能:取其高 /低 8位
CONST EQU 0ABCDH
MOV AH,HIGH CONST;AH=0ABH
运算符的优先级
1 () <> [] · LENGTH SIZE WIDTH MASK
2 PTR OFFSET SEG TPYE THIS,
3 HIGE LOW
4 * / MOD SHL SHR
5 + -
6 EQ NE GT LT GE LE
7 NOT
8 AND
9 OR XOR
10 SHORT
建议采用圆括号, ( ), 显式表
达, 它可以极大地提高程序的可阅读

§ 4.4 汇编语言的上机过程
编辑 文本编辑器,如 EDIT.COM
源程序:文件名,asm


汇编程序,如 MASM.EXE
目标模块:文件名,obj


连接程序,如 LINK.EXE
可执行文件:文件名,exe


调试程序,如 DEBUG.EXE
应用程序
错误
错误
错误
错误
汇编语言程序的开发过程
开发过程 — 源程序的编辑
? 源程序文件要以 ASM为扩展名
? 源程序文件的形成(编辑)可以通过任何
一个文本编辑器实现,
DOS中的全屏幕文本编辑器 EDIT
其他程序开发工具中的编辑环境
EDIT TEST.ASM
开发过程 — 源程序的汇编
? 汇编是将源程序翻译成由机器代码组成的目标
模块文件的过程
? MASM 5.x/6.x提供的汇编程序是 MASM.EXE,
MASM TEST.ASM
? 如果源程序中没有语法错误,MASM将自动生
成一个目标模块文件( TEST.OBJ); 否则
MASM将给出相应的错误信息
? 这时应根据错误信息,重新编辑修改源程序后,
再进行汇编
开发过程 — 目标模块的连接
? 连接程序能把一个或多个目标文件和库文件合
成一个可执行程序(,EXE,.COM文件),
LINK TEST.OBJ
? 如果没有严重错误,LINK将生成一个可执行文
件( TEST.EXE); 否则将提示相应的错误信

? 这时需要根据错误信息重新修改源程序后再汇
编、链接,直到生成可执行文件
开发过程 — 可执行程序的调试
? 经汇编、连接生成的可执行程序在操作系统下
只要输入文件名就可以运行,
TEST
? 操作系统装载该文件进入主存,并开始运行
? 如果出现运行错误,可以从源程序开始排错,
也可以利用调试程序帮助发现错误
? 采用 DEBUG.EXE调试程序,
DEBUG TEST.EXE