80x86汇编语言
清 华 大 学 出 版 社
第 1 章 绪 论
本章先介绍汇编语言的一些基本概念, 然后介绍数据的表示和类型, 最后简单介绍了
Intel 的 x86 家族历代微处理。
1. 1 汇编语言概述
尽管在使用汇编语言进行程序设计之前, 完全理解汇编语言的特点有困难, 但了解汇
编语言的特点对学习汇编语言程序设计是有益的。本节先说明汇编语言的内容, 再介绍汇
编语言的特点和使用汇编语言的场合。
1. 1. 1 汇编语 言
1. 机器语言
CPU 能直接识别并遵照执行的指令称为机器指令。机器指令在形式上表现为二进制
编码。机器指令一般由操作码和操作数两部分构成, 操作码在前, 操作数在后。操作码指
出要进行的操作或运算, 如加、减、传送等。操作数指出参与操作或运算的对象, 也指出操
作或运算结果存放的位置, 如 CP U 的寄存器、存储单元和数据等。
机器指令与 CPU 有着密切的关系。 通常, CPU 的 种类不同, 对应的机器指 令也
就不同。不同型号 CPU 的指令集往往有较大的差异。 但同一个系列 CP U 的指令集常
常具有良好 的向上兼容性, 也即下一代 CPU 的指令 集是上一代 CPU 指令 集的超 集。例
如, IN T EL 80386 指令集包含了 8086 指令集。
机器语言是用二进制编码的机器指令的集合及一组使用机器指令的规则。它是 CPU
能直接识别的唯一语言。只有用机器语言描述的程序, CPU 才能直接执行。用机器语言描
述的程序称为目的程序或目标程序。
为了阅读和书写方便, 常用十六进制形式或八进制形式表示二进制编码。例如, 我们
用 IN T EL 8086 指令写一个两数相加的程序片段。 具体要求是把偏移 2200H 存储单元
中的数与偏移 2201H 存储单元中的数相加, 将它们的和送入偏移 2202H 存储单元。完成
这一工作的程序片断包含三条机器指令, 用十六进制形式表示如下:
A 0 00 20
02 06 01 20
A 2 02 20
几乎没有人能直接看出该程序片段的功能, 原因是程序员难以掌握机器语言。因此,
程序员难以用机器语言写程序, 更难写出健壮的程序; 用机器语言编制出的程序也不易为
人们理解、记忆和交流。所以, 只是在早期或不得已时才用机器语言写程序, 现在几乎没有
人用机器语言写程序了。机器语言有如下缺点: 机器语言不能用人们熟悉的形式来描述计
·2·
算机要执行的 任务; 用机 器语言编写程 序十分 繁难, 极易出错; 一 旦有错, 也很难 发现, 也
即调试困难。
2. 汇编语言
为了克服机器语言的上述缺点, 人们采用便于记忆、并能描述指令功能的符号来表示
指令的操作码。这些符号被称为指令助记符。助记符一般是说明指令功能的英语词汇或
者词汇的缩写。同时也用符号表示操作数, 如 CP U 的寄存器、存储单元地址等。
用指令助记符、地址符号等符号表示的指令称为汇编格式指令。
汇编语言是汇编格式指令、伪指令的集合及其表示、使用这些指令的一组规则。伪指
令的概念留待以后介绍。用汇编语言书写的程序称为汇编语言程序, 或称为汇编语言源程
序, 或简称为源程序。
利用汇编语言, 上述两数相加的程序片断可表示如下:
MOV A L, VA R 1
A DD
A L, VA R 2
MOV
V AR 3, AL
显然, 汇编格式指令比二进制编码的机器指令要容易掌握得多, 用汇编语言编写的程
序要比用机器语言编写的程序容易理解、调试和维护
3. 汇编程序
由于 CPU 能 直接 识别 的唯一 语言 是机器 语言, 所 以用汇 编语 言编 写的 源程 序必 须
被翻译成用 机器语言表示的 目标程序后才能 由 CPU 执 行。把汇编 语言源程 序翻译成 目
标程序的过程称为汇编。完成汇编任务的程序叫做汇编程序。汇编过程如图 1. 1 所示。
1. 1. 2 汇编语 言的特点
由于汇编语言 使用指令助记符 和符号 地址,
所以它要比机器语言容易掌握得多。与高级语言
相比较, 汇编语言有如下特点。
1. 汇编语言与机器关系密切
因为汇编格式 指令是机器指令 的符号 表示,
图 1. 1 汇编过程示意图
所以汇编格式指令与机器有着密切的关系, 因此汇编语言也与机器有着密切的关系, 确切
地说汇编语言与机器所带的 CPU 有着十分密切的关系。对于各种不同类型的 CPU , 要使
用各种不同的汇编语言。于是, 对于各种不同类型的 CP U , 也就有各种不同的汇编程序。
由于汇编语言与机器关系十分密切, 所以汇编语言源程序与高级语言源程序相比, 它
的通用性和可移植性要差得多。但通过汇编语言可最直接和最有效地控制机器, 这常常是
大多数高级语言难以做到的。
2. 汇编语言程序效率高
用汇编语言编写的源程序在汇编后所得的目标程序效率高。这种目标程序的高效率
反映在时间和空间两个方面: 其一是运行速度快; 其二是目标程序短。在采用相同算法的
前提下, 任何高级语言程序在这两方面的效率都不如汇编语言程序, 许多情况下更是远远
不及。
·3·
汇编语言 程序能获得“时空”高效率的主 要原因是: 构成 汇编语 言主体的 汇编格式 指
令是机器指令的符号表示, 每一条汇编格式指令都是所对应的某条机器指令的“化身”; 另
一个重要原因是汇编语言程序能直接并充分利用机器硬件系统的许多特性。高级语言程
序在上述两点上要逊色得多。
3. 编写汇编语言源程序繁琐
编写汇编语言源程序要比编写高级语言源程序繁琐得多。汇编语言是面向机器的语
言, 高级语言是面向过程或面向目标、对象的语言。如下两点突出表现了汇编语言的这一
特性:
作为机器指令符号化的每一条汇编格式指令所能完成的操作极为有限。例如, Z80 指
令集中没有乘法指令, 8088 指令集中没有能够同时完成两次算术运算的指令。
程序员在利用汇编语言编写程序时, 必须考虑包括寄存器、存储单元和寻址方式在内
的几乎所有细节问题。例如: 指令执行对标志的影响, 堆栈设置的位置等。在使用高级语
言编写程序时, 程序员不会遇到这些琐碎却重要的问题。
4. 汇编语言程序调试困难
调试汇编语言程序往往要比调试高级语言程序困难。汇编格式指令的功能有限和程
序员要注意太 多的细节问题是 造成这种困难 的两个客 观原因; 汇编 语言提供 给了程序 员
最大的“舞台”, 而程序员往往为了追求“时空”上的高效率而不顾程序的结构, 这是造成调
试困难的主观原因。
1. 1. 3 恰当地 使用汇编 语言
1. 汇编语言的优缺点
为了恰当地使用汇编语言, 我们先明确一下它的优缺点。
汇编语言的主要优点是利用它可能编写出在“时空”两个方面最有效率的程序。另外,
通过它可最直接和最有效地操纵机器硬件系统。
汇编语言的主要缺点是它面向机器, 与机器关系密切, 它要求程序员比较熟悉机器硬
件系统, 要考虑许多细节 问题, 最 终导致程 序员编写 程序繁琐; 调 试程序困 难; 维 护、交 流
和移植程序更困难。
正是由于汇编 语言与机器关系 密切, 才 使汇编 语言具有 其他高 级语言所 不具备的 上
述优点和缺点。为了利用汇编语言的优点, 必须付出相应的代价。但汇编语言的每一个优
点常常闪耀出诱人的光芒, 使人们勇敢地面对它的缺点。
2. 使用汇编语言的场合
根据汇编语言的优缺点, 我们要恰当地使用汇编语言, 即尽可能地“扬长避短”。是否
利用汇编语言编写程序, 要看具体的应用场合, 要充分考虑到软件的开发时间和软件的质
量等诸多方面的因素。我们认为下列应用场合, 可考虑使用汇编语言编写程序。
( 1) 对软件的执行时间或存储容量有较 高要求的场合。例如: 系统程 序的关键核心,
智能化仪器仪表的控制系统, 实时控制系统等。
( 2) 需要提高大型软件性能的场合。通常把大 型软件中执行频率 高的子程序( 过程)
用汇编语言编写, 然后把它们与其他程序一起连接。
·4·
( 3) 软件 与硬件 关系密切, 软件 要有直 接和有效 控制硬 件的场合。 如设备驱 动程 序
等。
( 4) 没有合适的高级语言的场合。
3. 适度地追求“时空”效率
在用汇编语言编写程序时, 追求“时空”效率要适度。在编写汇编语言程序时, 我们要
尽量利用最恰当的指令, 以便节约一个字节或节省几个机器周期。但时至今日, 计算机硬
件系统的整体 性能已极大地提 高, 所以, 除非 不得已, 不要为 节约少 量字节或 机器周期 而
影响程序的结构性、健壮性和可读性等。要在确保汇编语言程序上述性能良好的前提下追
求“时空”性能。
1. 2 数据的表示和类型
熟悉数据在计算机内的表示形式是掌握汇编语言程序设计的关键之一。本节简单介
绍数据的表示形式和类型。
计算机中存储信息的最小单位称为位, 在绝大数多系统中它只能表示两种状态。这两
种状态可分别代表 0 和 1。计算机系统内部采用二进制表示数值数据, 也采用二进制编码
表示非数值数据和指令, 其主要原因就在于此。
1. 2. 1 数值数 据的表示
所谓数值数据就是数。这里仅介绍定点整数的有关内容。
1. 数的二进制表示
尽管日常生活中大多采用十进制计数, 但在计算机内, 数却大多采用二进制表示。某
个二进 制数 b nb n- 1…b 2b 1b 0 所 表示的 数值 用十 进制数 来衡 量时, 可利 用如 下按权 相加 的
方法计算得到:
b n2n+ b n - 12n - 1+ …+ b 222+ b 121+ b 02 0
在书写时, 为了与十进制数相区别, 通常在二进制数后加一个字母 B。
2. 有符号数的补码表示
为了方便地表示负数和容易地实现减法操作, 有符号数采用补码形式表示。所以, 有
符号数二进制表示的最高位是符号位, 0 表示正数, 1 表示负数。正数数值的补码形式用二
进制表示。为得到一个负数数值的补码形式, 方法可以是先得出该负数所对应正数的二进
制形式, 然后使正数的每一个二进制位变反, 最后再将变反的结果加 1。
3. 符号扩展
常常需 要把一个 n 位二进制数 扩展成 m 位二进制数( m > n) 。当 要扩展的数是无 符
号数时, 只要在最高位前扩展( m - n ) 个 0。如果要扩展的数是有符号数, 并且采用补码形
式表示, 那么, 就要进行符号位的扩展。
例如, 21 的 8 位二进制和 16 位的二进制补码如下:
00010101
8 位
·5·
0000000000010101 16 位
例如, - 3 的 8 位二进制补码和 16 位二进制补码如下:
11111101
8 位
1111111111111101 16 位
4. 数值数据的表示范围
n 位二进制数能够表示的无符号整数的范围是:
0 ≤I ≤ 2n- 1
采用补码形式表示有符号数。那么 n 位二进制数能够表示的有符号整数的范围是:
- 2( n - 1 ) ≤ I ≤ + 2 ( n- 1) - 1
所以, 如果 n 是 8, 那么能够表示的无 符号整数 的范围是 0~ 255, 能够表 示的有符 号
整 数的 范 围 是 - 128~ + 127; 如 果 n 是 16, 那 么 能 够 表 示 的 无 符 号 整 数 的 范 围 是 0 ~
65535, 能够表示的有符号整数的范围是- 32768~+ 32767。
5. BCD 码
虽然二进制数 实现容易, 并且二进制 运算规 律简单, 但不符 合人们 的使用习 惯, 书 写
阅读都不方便。所以在计算机输入输出时通常还是采用十进制来表示数, 这就需要实现十
进 制 与二 进 制间 的 转换。 为了 转 换方 便, 常 采 用二 进 制 编码 的 十进 制, 简 称 为 BCD 码
( Binary Coded Decimal) 。
表 1. 1 十进制数字的 8421 BCD 码
十进制数字
8421 BCD 码
十进制数字
8421 BCD 码
0
1
2
3
4
0000
0001
0010
0011
0100
5
6
7
8
9
0101
0110
0111
1000
1001
BCD 码就是用 4 位二进制数编码 表示 1 位十进制 数。表示的方法可 有多种, 常 用的
是 8421 BCD 码, 它的表示规则如表 1. 1 所示。从表 1. 1 可见, 8421 BCD 码最自然和最简
单。例如, 十进制数 1996 用 8421 BCD 码表示成 0001 1001 1001 0110, 每组 4 位二进制数
之 间 是 二 进 制 的, 但 组 与 组 之 间 是 十 进 制 的。和 十 进 制 数 1996 等 值 的 二 进 制 数 是
11111001100。
6. 十六进制表示
由于二进制数的基数太小, 所以书写和阅读都不够方便。而十六进制数的基数 16 等
于 2 的 4 次幂, 于是二进制 数与十六进制数之 间能方便地转换, 也即 4 位二进制数对应 1
位十六进制数, 或者 1 位十六进制数对应 4 位二进制数。因此, 人们常常把二进制数改写
成十六进制数, 在汇编语言程序设计过程中尤其如此。
在书写时, 为了区别于十进制数和二进制数, 通常在十六进制数后加一个字母 H 。
·6·
1. 2. 2 非数值数 据的表示
计算 机除了 处理 数值数 据外, 还 要处理 大量 的非 数值数 据, 如文 字信 息 和图 表信 息
等, 为 此必须对非数值数 据进行编码, 这样不 仅计算机 能够方便 地处理 和存储它 们, 而 且
还可以赋于它们数值数据的某些属性。
1. ASCII 码
美国 信息交 换标准 码( American Standard Code for Informat ion Int erchange) , 简 称
为 A SCII 码, 是目 前国际上 比较通用 的字 符二 进制编 码, 微型 计算机 中也 普遍采 用它 作
为字符的编码。它是 7 位二进制编码, 表 1. 2 列出了 ASCII 码。
从表 1. 2 可看到, 它对 94 个常用的一般符号进行了编码, 其中包括 26 个英文字母的
大小写符号、10 个数字符号和 32 个其他符号。空格( SP ) 也作为一个符号, 其编码是 20H ,
它界于一般符号和 32 个 控制符之间。码值小 于 20H 的是控制符 号, 例如, 回车符号 的码
值是 0DH , 用符号 CR 表示。所有这些一般符号和控制符统称为字符。从表 1. 2 还可看到,
数字符号的编码、大写字母符号的编码和小写字母符号的编码分别是连续的, 所以只要记
住数 字符号 的编 码从 30H 开始、大 写字 母符号 的编 码从 41H 开始 和小 写字 母的 编码 从
61H 开始, 那么就可推出其他数字符号和字母符号的编码。
由于 ASCII 码只使 用了 7 位二进制 进行编码, 故最多表示 128 个 字符。这往往不 能
满足使用要求。为此在 IBM P C 系列及其兼容机上, 使用扩展的 ASCII 码。扩展的 A SCII
码使用 8 位 二进制进行编码, 故可表示 256 个字符。另外, 在该扩展的 ASCII 码中, 控 制
符所对应的编码同时也表示其他图形符号。
2. 变形国标码
有了 ASCII 码, 计算机就能 处理数字、字母等字符, 但还不能处理 汉字符。为了使 计
算机能够处理汉字信息, 就必须对汉字进行编码。我国在 1981 年 5 月对六千多个常用汉
字制定了 交换码的国家标 准, 即 GB2312—80《信息交 换用汉字 编码字符 集—— 基本 集》。
该标准规定了 汉字信息交换用 的基本汉 字符和一 般图形字 符, 它们共计 7445 个, 其中 汉
字分成两级共计 6763 个。该标准同时也给定了它们的二进制编码, 即国标码。
国标码是 16 位编码, 高 8 位表示汉字符的区号, 低 8 位表示汉字符的位号。实际上,
为了 给汉 字符 编码, 该标 准把 代码表 分成 94 个区, 每个 区有 94 个位。区 号 和位 号都 从
21H 开始。一级汉字安排在 30H 区至 57H 区, 二级汉字安排在 58H 区至 77H 区。例如,
“啊”字的国标码是 3021H 。国标码为汉字的输入提供了一种标准输入方式。
000
0
001
1
表 1. 2 ASCII 码表
010
011
100
101
110
2
0
!
"
3
@
1
2
4
P
A
B
5
`
Q
R
6
p
a
b
0000
0001
0010
0
1
2
111
7
b
q
r
·7·
000
0
001
1
010
011
100
101
110
111
2
#
$
%
&
'
(
)
*
+
,
-
.
/
3
3
4
5
6
7
8
9
:
;
<
=
>
?
4
C
D
E
F
G
H
I
J
K
L
M
N
O
5
S
T
U
V
W
X
Y
Z
[
\
]
^
_
6
c
d
e
f
g
h
i
j
k
l
m
n
o
7
s
t
u
v
w
x
y
z
{
©¦
}
~
0011
0100
0101
0110
0001
1000
1001
1010
1011
1100
1101
1110
1111
3
4
5
6
7
8
9
A
B
C
D
E
F
目前在计算机中文平台中普遍采用的汉字编码是变形国标码。变形国标码是 16 位二
进制编码, 顾名思义它是国标码的变形。用得最多的变形方法是把国标码的第 15 位和第
7 位均置成 1, 由于国标码中第 15 位和第 7 位 都是 0, 所以这种变形 方法实际上就是 在国
标码上加 8080H 。
尽管 16 位的 变形国 标码 与两个 扩展 的 ASCII 码 的组 合有冲 突, 但它 在相关 系统 模
块的支持下, 有效地实现了汉字在计算机内的表示。
1. 2. 3 基本数 据类型
计算机存取的以二进制位表示的信息位数一般是 8 的倍数, 它们有专门的名称。
1. 字节
一个字节由 8 个二进制位组成。字节的最低位一般称为第 0 位, 最高位称为第 7 位,
如图 1. 2 所示。
图 1. 2 一个字节 8 个位
通常, 硬件存储器的每一存储单元就由 8 个连续的位组成, 也即可用于存储一个字节
的信息。
如用一个字节来表示一个无 符号数, 那 么表示范围是 0~255; 如表示 有符号数, 则表
·8·