1、第 1 章 汇编语言基础知识 3第 1 章 汇编语言基础知识本章介绍学习汇编语言程序设计所必须具备的基本知识,主要包括汇编语言的基本概念及计算机中数据的表示方法。通过本章的学习,读者应能了解汇编语言概念及其使用的进位计数制、不同进位计数制之间的转换、计算机编码以及基本数据类型。本章内容要点: 汇编语言的概念 汇编语言的特点 不同进位计数制之间的转换 计算机编码1.1 汇编语言概述1.1.1 汇编语言基本概念自然语言是具有特定语音和语法等规范的、用于人类表达思想并实现相互交流的工具。人与人之间只有使用同一种语言才能进行直接交流,否则就必须通过翻译。要使计算机为人类服务,人们就必须借助某种工具,告
2、诉计算机“做什么”甚至“怎么做” ,这种工具就是程序设计语言。程序设计语言通常分为三类:机器语言、汇编语言和高级语言。而前两种语言与机器密切相关,统称为低级语言。1机器语言机器语言是计算机第一代语言,它全部由 0、1 代码组成,是能够直接被机器所接受的语言,是最底层的计算机语言。机器语言不容易记忆,程序编写难度大,调试修改繁琐,且不易移植,现在程序员很少用。但机器语言执行速度最快,它是一种面向机器的程序设计语言。2汇编语言为了克服机器语言难以记忆、表达和阅读的缺点,人们采用具有一定含义的符号作为助忆符,用指令助忆符、符号地址等组成的符号指令称为汇编格式指令(或汇编指令) 。例如,用 ADD 表
3、示加法指令,SUB 表示减法指令,MOV 表示传送指令等。汇编语言是汇编指令集、伪指令集和使用它们规则的统称。伪指令的概念将在第 4 章介绍。汇编语言比机器语言直观,容易记忆和理解,用汇编语言编写的程序也比机器语言程序易读、易检查、易修改。对于不同的计算机,针对同一问题所编写的汇编语言源程序是互不通用的。8086/8088 和基于 RAM 核汇编语言程序设计4用汇编语言编写的程序执行效率比较高,但通用性与可移植性仍然比较差。计算机不能直接识别用汇编语言编写的程序,必须由一种专门翻译程序将汇编语言程序翻译成机器语言程序,计算机才能执行。例如,在 8086 机器下,分别用汇编语言和机器语言计算 1
4、0+20 的程序代码如下:汇编语言 机器语言MOV AL,10 B0 0AADD AL,20 04 14显然,使用汇编语言编写的程序要比机器语言更容易理解。3高级语言机器语言和汇编语言以外的程序设计语言统称高级语言。其特点是更加接近自然语言和惯用的数学表达形式,与计算机硬件结构无关,因而便于使用,便于交流和推广。例如,可以在程序中直接使用表达式 10+20。目前,常用的高级语言数十种,如C、C+ 、Pascal 、Basic、Java 等。高级语言可分成编译型和解释型高级语言,需要分别使用编译程序和解释程序将源程序翻译成机器语言程序,才能交计算机执行。总之,高级语言编程效率高,但运行效率低。1
5、.1.2 汇编语言的特点汇编语言相对机器语言而言好记好用,但远不如高级语言方便、实用,而且编写同样的程序,使用汇编语言比使用高级语言花费的时间更多,调试和维护更困难,在计算机速度大大提高和存储器容量大大增加的今天,高级语言的使用更为广泛和普遍(特别是编写大型程序) 。既然如此,为什么还要使用汇编语言呢?主要有两个原因:性能和对计算机的完全控制。一般而言,汇编语言具有如下特点:(1)执行速度快一个汇编语言程序,要比高级语言程序执行得更快。程序的执行速度对于某些应用来说是至关重要的。对于这些应用,单纯使用高级语言往往达不到要求,单纯使用汇编语言编写程序也并不是最好的方案,许多成功的大型应用程序往往
6、使用的是混合编程。首先使用高级语言编写整个程序,然后测试程序的执行时间,再使用汇编语言重写其中最费时间的部分。这样做的依据是在实际使用中,通常程序的大部分执行时间都花费在一小部分代码上。例如编写图像处理程序,就往往使用汇编语言编写软件中的关键部分。(2)程序短小一个汇编语言程序,要比高级语言程序更小。在某些情况下,设备中的嵌入式处理器往往只有很少的内存,使用汇编语言可能是唯一的方法。如智能卡中有 CPU,但是智能卡中很难有 1 MB 以上的内存,也不可能有带分页的硬盘,但智能卡又必须执行复杂的加密解密计算。个人数字助理(PDA)和其他使用电池作为能源的无线电子设备,为了节省电池的电力,往往也只
7、有很少的内存,它们也需要使用短小精悍而且具有高效率的机器代码。(3)可以直接控制硬件某些应用程序要求能够完全控制计算机硬件,这也必须使用汇编语言。如操作系统中的低级中断和陷阱处理程序以及许多嵌入式实时系统中的设备控制程序都属于这一类应用。第 1 章 汇编语言基础知识 5(4)可以方便地编译编译器可以产生供编程者使用的汇编程序或者自己执行汇编过程。因此,为了理解编译器的工作原理,必须首先理解汇编语言。(5)辅助计算机工作者掌握计算机体系结构研究汇编语言可以使人们清楚实际计算机结构。特别是对于学习计算机体系结构的学生,编写汇编语言是在结构层理解计算机的唯一途径。(6)程序编制耗时,可读性差用汇编语
8、言编制程序十分费时,而且程序的质量直接受到程序员技术水平的影响,程序的可读性也很差。就如前面所举的加法计算的例子,用高级语言编程只需写一条加法表达式,简单明了,极其直观。而用汇编语言编程则需写出两条指令,这些指令都是些对硬件的操作,因此程序的可读性很差。(7)程序可移植性差由于汇编语言是面向硬件的,所以用汇编语言编制的程序可移植性很差。显而易见,不同的 CPU 都有相互独立的指令系统,相互间无任何关系,就算是使用同一系列 CPU 的机器,因其外围硬件可能有差别,这也会使相同的程序在不同的机器上无法通用。不难看出,汇编语言存在很多的弱点,但由于它具有一些高级语言所不具备的突出优点,所以汇编语言的
9、应用范围还是很广的。特别是当用户需要研究计算机具体的工作原理的时候,还必须要掌握汇编语言。1.2 进位计数制及其转换计算机内部的信息分为两大类:控制信息和数据信息。控制信息是一系列的控制命令,用于指挥计算机如何操作;数据信息是计算机操作的对象,一般又可分为数值数据和非数值数据。数值数据用于表示数量的大小,它有确定的数值;非数值数据没有确定的数值,它主要包括字符、汉字和逻辑数据等等。对计算机而言,不论是控制命令还是数据,它们都要用“0”和“1”两个基本符号即基2 码来编码表示,这是由于以下三个原因:(1)基 2 码在物理上最容易实现。例如,用高、低两个电位表示“1”和“0” ,或用脉冲的有、无表
10、示“1”和“0” ,用脉冲的正、负极性表示“1”和“0”等等,可靠性都较高。(2)基 2 码用来表示二进制数,其编码及加减运算规则简单。(3)基 2 码的两个符号“1”和“0”正好与逻辑数据“真”与“假”相对应,为计算机实现逻辑运算带来了方便。因此,不论是什么信息,在输入计算机内部时,都必须用基 2 码编码表示,以方便存储、传送和处理。8086/8088 和基于 RAM 核汇编语言程序设计61.2.1 数与数制1数的表示 进位计数制是一种计数的方法。在日常生活中,人们使用各种进位计数制,如六十进制(1 小时=60 分, 1 分=60 秒) ,十二进制(1 英尺=12 英寸, 1 年=12 月)
11、等。但人们最熟悉和最常用的是十进制计数。按进位的原则进行计数叫进位计数制,简称数制。每种数制都有其基数和各数位的位权。基数是指该数制中允许选用的基本数码的个数。每个数码所表示的数值等于该数码乘以一个与数码所在位置有关的常数,这个常数叫位权,位权的大小是以基数为底,数码所在位置的序号为指数的整数次幂。在汇编语言中常用的进位计数制有:二进制、八进制、十进制和十六进制,其基数、数码和进位关系如表 1-1 所示。表 1-1 几种常用的进位计数制的基数、数码和进位关系计数制 基数 数 码 进位关系二进制 2 0、1 逢二进一八进制 8 0、1、2、3、4、5、6、7 逢八进一十进制 10 0、1、2、3
12、、4、5、6、7、8、9 逢十进一十六进制 16 0、1、2、3、4、5、6、7、8、9A、B、C、D、E、F 逢十六进一在十进制数中,个位的位权为 100,十位的位权为 101,百位的位权为 102,千位的位权为 103,而在小数点后第一位上的位权为 101,小数点后第二位的位权为 102等等。因此,如果有十进制数 123.45,则百位上的 1 表示 1 个 100,十位上的 2 表示 2 个 10,个位上的 3表示 3 个 1,小数点后第一位上的 4 表示 4 个 0.1,小数点后第二位上的 5 表示 5 个 0.01,用位权表示成:(123.45)10 =1102+2101+3100+4
13、10-1+510-2同理,任意一个二进制数、八进制数和十六进制数也可用位权表示。例如:(101.01)2=122+021+120+02-1+12-2(125.46)8 =182+281+580+481+682(AD.5F)16 =A161+D160+5161+F162据上述概念,可推广出表示任意进制数的通式:N= ri=( ri + ri)xnim0ni1mx其中 ri 为整数部分, ri 为小数部分。r 为基数,每一项的数字可用 0r-1 数0nix1i字中的一个数字来表示。2计数制的书写规则为了区别不同的计数制,可采用下列两种方法:第 1 章 汇编语言基础知识 7(1)在数字后面加写相应的
14、英文字母作为标识,英文字母不分大小写。本书约定采用大写字母形式。如:1100011B 。B 后缀表示为二进制数( Binary) 。2357O。O 后缀表示为八进制数(Octal) 。由于英文字母 O 容易和零误会,所以也可以用 Q 来表示八进制。1000D。D 后缀表示为十进制数(Decimal) 。3AB5H。H 后缀表示为十六进制数(Hexadecimal) 。如果记数符号 a,b,c,d,e,f 打头,头部应加 0,如 0A8F5H;记数符号 a,b,c,d,e, f 不区别大小写,与 ABCDEF 等效。缺省后缀时,一般约定为十进制数。(2)在括号外面加数字下标。如:(1011) 2
15、 表示二进制数的 1011(2DF2)16 表示十六进制数的 2DF2 1.2.2 不同数制之间的转换1十进制数与二进制数之间的转换(1)十进制整数转换成二进制整数方法:除 2 取余法注意:第一次得到的余数为二进制数的最低位,最后得到的余数为二进制数的最高位。例 1.1 将十进制数 97 转换成二进制数。其过程如下:即 A0=1即 A1=0即 A2=0即 A3=0即 A4=0即 A5=1即 A6=1结束最后结果为:(97) 10 =(A6 A5 A4 A3 A2 A1 A0)2=(1100001)2(2)十进制小数转换成二进制小数方法:乘 2 取整法注意:最后将每次得到的整数部分(必定是 0
16、或 1)按先后顺序从左到右排列即得到所对应二进制小数。例 1.2 将十进制小数 0.8125 转换成二进制小数。其过程如下:2 972 482 242 122 62 32 1商为 0余数为 1,余数为 0,余数为 0,余数为 0,余数为 0,余数为 1,余数为 1,余数为 08086/8088 和基于 RAM 核汇编语言程序设计80.8125 2 1.6250 整数部分为 1,即 A1=10.6250 余下的小数部分 2 1.2500 整数部分为 1,即 A2=10.2500 余下的小数部分 2 0.5000 整数部分为 0,即 A3=00.5000 余下的小数部分 2 1.0000 整数部分
17、为 1,即 A4=10.0000 余下的小数部分为 0,结束最后结果为:(0.8125) 10=(0.A1A2A3A4) 2 =(0.1101)2(3)一般的十进制数转换成二进制数为了将一个既有整数又有小数部分的十进制数转换成二进制数,可以将其整数部分和小数部分分别进行转换,然后再组合起来。例 1.3 将(97.8125) 10 转换成二进制数。其过程如下:(97) 10=(1100001)2 (0.8125)10=(0.1101)2 由此可得:(97.8125) 10 =(1100001.1101)2 (4)二进制数转换十进制数方法:按位权展开后相加。注意:用其各位所对应的系数,按“位权展开
18、求和”的方法就可以得到,其基数为 2。例 1.4 将(101.11) 2 转换成十进制数。其过程如下:(101.11)2=122+021+120+121+122=4+0+1+0.5+0.25=(5.75) 102. 十进制与八进制之间的转换(1)十进制整数转换成八进制整数方法:除 8 取余法。注意:采用基数 8 连续去除该十进制整数,直至商等于“0”为止,然后逆序排列所得到的余数。例 1.5 将十进制数 97 转换成八进制数。其过程如下:8 97 余数为 1, 即 A0=18 12 余数为 4, 即 A1=48 1 余数为 1, 即 A2=10 余数为 0, 结束最后结果为:(97) 10(A
19、 2 A1 A0) 8=(141)8(2)十进制小数转换成八进制小数方法:乘 8 取整法。注意:连续用基数 8 去乘以该十进制小数,直至乘积的小数部分等于“0” ,然后顺序排第 1 章 汇编语言基础知识 9列每次乘积的整数部分。例 1.6 将十进制小数 0.6875 转换成八进制小数。其过程如下:0.6875 8 5000 整数部分为 5,即 A 1=50.5000 余下的小数部分 8 4.0000 整数部分为 4,即 A 2=40.0000 余下的小数部分为 0,结束最后结果为: (0.6875)10 =(0.A1A2)8=(0.54)8(3)八进制数转换成十进制数方法:按位权展开后相加。用
20、其各位所对应的系数,按“位权展开求和”的方法就可以得到,其基数为 8。例 1.7 将(141.54) 8 转换为十进制数。其过程如下:(141.54)8=182+481+180+581+482=64+32+1+0.625+0.0625=97.6875最后结果为:(141.54) 8 =(97.6875)103. 十进制与十六进制之间的转换(1)十进制整数转换成十六进制整数方法:除 16 取余法。注意:采用基数 16 连续去除该十进制整数,直至商等于“0”为止,然后逆序排列所得到的余数。例 1.8 将十进制整数(2347) 10 转换为十六进制整数,采用“除 16 倒取余”的方法,过程如下:16
21、 2347 余数为 11, 即 A0=B(十六进制数为 B)16 146 余数为 2, 即 A1=216 9 余数为 9, 即 A2=90 余数为 0, 结束最后结果为:(2347) 10(A 2 A1 A0)16=(92B)16(2) 十进制小数转换成十六进制小数方法:乘 16 取整法。注意:连续用基数 16 去乘以该十进制小数,直至乘积的小数部分等于“0” ,然后顺序排列每次乘积的整数部分。例 1.9 将十进制小数 0.6875 转换成十六进制小数。其过程如下:0.6875 16 11.0000 整数部分为 11,即 A1=B0.0000 余下的小数部分为 0,结束最后结果为:(0.687
22、5) 10 =(0.A1)16 =(0.B)168086/8088 和基于 RAM 核汇编语言程序设计10(3)十六进制数转换十进制数方法:按位权展开后相加。注意:用其各位所对应的系数,按“位权展开求和”的方法就可以得到,其基数为 16。例 1.10 将(92B.B) 16 转换成十进制数。其过程如下:(92B.B)16=9162+2161+B160+B161=9162+2161+11160+11161=2347.6875最后结果为:(92B.B) 16=(2347.6875)104. 二进制与八进制、十六进制数之间的转换因为:2 3=8,所以每三位二进制数对应一位八进制数;24=16,所以每
23、四位二进制数对应一位十六进制。表 1-2 列出了十进制、二进制、八进制、十六进制最基本的数字的对应关系。这些对应关系在后面的二进制、八进制、十六进制相互转换中要经常用到。(1)二进制数转换成八进制数从小数点所在位置分别向左向右每三位一组进行划分。若小数点左侧的位数不是 3 的整数倍,在数的最左侧补零;若小数点右侧的位数不是 3 的整数倍,在数的最右侧补零。然后参照表 1-2,将每三位二进制数转换成对应的一位八进制数,即为二进制数对应的八进制数。表 1-2 十、二、八、十六进制数码的对应关系 十进制 二进制 八进制 十六进制0 0000 0 01 0001 1 12 0010 2 23 0011
24、 3 34 0100 4 45 0101 5 56 0110 6 67 0111 7 78 1000 10 89 1001 11 910 1010 12 A11 1011 13 B12 1100 14 C13 1101 15 D14 1110 16 E15 1111 17 F例 1.11 将(11010.11) 2 转换为八进制数。其过程如下:011 010 . 1103 2. 6所以 (11110.11)2 =(32.6)8(2)八进制数转换成二进制数第 1 章 汇编语言基础知识 11方法:参照表 1-2,将每一位八进制数转换成对应的三位二进制数,即为八进制数对应的二进制数。例 1.12 将
25、(34.6) 8 转换为二进制数。其过程如下:3 4. 6011 100. 110所以(34.6) 8=(11100.11)2 (3)二进制数转换成十六进制数从小数点所在位置分别向左向右每四位一组进行划分。若小数点左侧的位数不是 4 的整数倍,在数的最左侧补零;若小数点右侧的位数不是 4 的整数倍,在数的最右侧补零。然后参照表 1-2,将每四位二进制数转换成对应的一位十六进制数,即为二进制数对应的十六进制数。例 1.13 将(1011110.11) 2 转换为十六进制数。其过程如下:01011110.11005 E . C所以(1011110.11) 2=(5E.C) 16(4) 十六进制数转
26、换成二进制数方法:参照表 1-2,将每一位十六进制数转换成对应的四位二进制数,即为十六进制数对应的二进制数。例 1.14 将(E8.C) 16 转换为二进制数。其过程如下:E 8 C1110 1000 1100所以(E8.C) 16=(11101000.11)2八进制数和十六进制数主要用来简化二进制数的书写,因为具有 23=8,2 4=16 的关系,故使用八进制数和十六进制数表示的二进制数较短,便于记忆。IBMPC 机中主要使用十六进制数表示二进制数和编码,所以必须十分熟悉二进制数与十六进制数的对应关系。1.3 计算机中数与字符的表示方法计算机中数值型数据是用二进制数来表示的,而非数值型数据包
27、括英文字母、标点符号、专用符号、汉字等,也是用二进制数来编码的。1.3.1 数值型数据的编码1. 二进制数的编码及运算我们很容易想到,数据的正负号可用一位二进制的 0 和 1 两个状态来表示,这样,二进制数值数据在计算机中就能方便表示了。为了尽可能地简化对二进制数值数据进行算术运算用到的规则,机器将二进制数值数据进行编码表示。常用的编码有原码、反码和补码。由于补码编码有许多优点,大多数微机采用了补码编8086/8088 和基于 RAM 核汇编语言程序设计12码,所以我们着重介绍补码编码表示法。为了讨论方便,有必要引入两个概念:机器数和机器数的真值。 机器数:带符号的二进制数值数据在计算机内部的
28、编码。 真值:机器数所代表的实际值。一般机器数的最高有效位用来表示数的正负符号,0 表示正数,1 表示负数。(1)二进制数原码编码正数的符号位为 0,负数的符号位为 1,其它位按照一般的方法来表示数的绝对值。用这样的表示方法得到的就是数的原码。例 1.15 当机器字长为 8 位二进制数时:X1011011 X原码 01011011Y1011011 Y原码 110110111 原码 00000001 1 原码 10000001127 原码 01111111 127 原码 11111111原码表示的整数范围是:(2 n-11)(2 n-11) ,其中 n 为机器字长。则:8 位二进制原码表示的整数
29、范围是127127,16 位二进制原码表示的整数范围是3276732767。(2)二进制数反码编码对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以外的各位按位取反。例 1.16 当机器字长为 8 位二进制数时:X1011011 X原码 01011011 X反码 01011011Y1011011 Y原码 11011011 Y反码 101001001 反码 00000001 1 反码 11111110127 反码 01111111 127 反码 10000000负数的反码与负数的原码有很大的区别,反码通常用作求补码过程中的中间形式。反码表示的整数范围与原码相同。(3)二进制数补码编码正数的补码与其原码相同,负数的补码为其反码在最低位加 1。例 1.17 当机器字长为 8 位二进制数时,求 X 和 Y 的补码。