当前位置:文档之家› 第1章汇编语言知识学习基本知识

第1章汇编语言知识学习基本知识

第1章汇编语言知识学习基本知识
第1章汇编语言知识学习基本知识

第1章汇编语言基础知识

本章介绍学习汇编语言程序设计所必须具备的基本知识,主要包括汇编语言的基本概念及计算机中数据的表示方法。通过本章的学习,读者应能了解汇编语言概念及其使用的进位计数制、不同进位计数制之间的转换、计算机编码以及基本数据类型。

本章内容要点:

汇编语言的概念

汇编语言的特点

不同进位计数制之间的转换

计算机编码

1.1汇编语言概述

1.1.1 汇编语言基本概念

自然语言是具有特定语音和语法等规范的、用于人类表达思想并实现相互交流的工具。人与人之间只有使用同一种语言才能进行直接交流,否则就必须通过翻译。要使计算机为人类服务,人们就必须借助某种工具,告诉计算机“做什么”甚至“怎么做”,这种工具就是程序设计语言。

程序设计语言通常分为三类:机器语言、汇编语言和高级语言。而前两种语言与机器密

切相关,统称为低级语言。

1.机器语言

机器语言是计算机第一代语言,它全部由0、1代码组成,是能够直接被机器所接受的语言,是最底层的计算机语言。

机器语言不容易记忆,程序编写难度大,调试修改繁琐,且不易移植,现在程序员很少用。但机器语言执行速度最快,它是一种面向机器的程序设计语言。

2.汇编语言

为了克服机器语言难以记忆、表达和阅读的缺点,人们采用具有一定含义的符号作为助忆符,用指令助忆符、符号地址等组成的符号指令称为汇编格式指令(或汇编指令)。例如,用ADD表示加法指令,SUB表示减法指令,MOV表示传送指令等。汇编语言是汇编指令集、伪指令集和使用它们规则的统称。伪指令的概念将在第4章介绍。

汇编语言比机器语言直观,容易记忆和理解,用汇编语言编写的程序也比机器语言程序易读、易检查、易修改。对于不同的计算机,针对同一问题所编写的汇编语言源程序是互不通用的。

用汇编语言编写的程序执行效率比较高,但通用性与可移植性仍然比较差。计算机不能直接识别用汇编语言编写的程序,必须由一种专门翻译程序将汇编语言程序翻译成机器语言程序,计算机才能执行。

例如,在8086机器下,分别用汇编语言和机器语言计算10+20的程序代码如下:汇编语言机器语言

MOV AL,10 B0 0A

ADD AL,20 04 14

显然,使用汇编语言编写的程序要比机器语言更容易理解。

3.高级语言

机器语言和汇编语言以外的程序设计语言统称高级语言。其特点是更加接近自然语言和惯用的数学表达形式,与计算机硬件结构无关,因而便于使用,便于交流和推广。例如,可以在程序中直接使用表达式10+20。目前,常用的高级语言数十种,如C、C++、Pascal、Basic、Java等。

高级语言可分成编译型和解释型高级语言,需要分别使用编译程序和解释程序将源程序翻译成机器语言程序,才能交计算机执行。总之,高级语言编程效率高,但运行效率低。1.1.2 汇编语言的特点

汇编语言相对机器语言而言好记好用,但远不如高级语言方便、实用,而且编写同样的程序,使用汇编语言比使用高级语言花费的时间更多,调试和维护更困难,在计算机速度大大提高和存储器容量大大增加的今天,高级语言的使用更为广泛和普遍(特别是编写大型程序)。既然如此,为什么还要使用汇编语言呢?主要有两个原因:性能和对计算机的完全控制。一般而言,汇编语言具有如下特点:

(1)执行速度快

一个汇编语言程序,要比高级语言程序执行得更快。程序的执行速度对于某些应用来说是至关重要的。对于这些应用,单纯使用高级语言往往达不到要求,单纯使用汇编语言编写

程序也并不是最好的方案,许多成功的大型应用程序往往使用的是混合编程。首先使用高级语言编写整个程序,然后测试程序的执行时间,再使用汇编语言重写其中最费时间的部分。这样做的依据是在实际使用中,通常程序的大部分执行时间都花费在一小部分代码上。例如编写图像处理程序,就往往使用汇编语言编写软件中的关键部分。

(2)程序短小

一个汇编语言程序,要比高级语言程序更小。在某些情况下,设备中的嵌入式处理器往往只有很少的内存,使用汇编语言可能是唯一的方法。如智能卡中有CPU,但是智能卡中很难有1 MB以上的内存,也不可能有带分页的硬盘,但智能卡又必须执行复杂的加密解密计算。个人数字助理(PDA)和其他使用电池作为能源的无线电子设备,为了节省电池的电力,往往也只有很少的内存,它们也需要使用短小精悍而且具有高效率的机器代码。

(3)可以直接控制硬件

某些应用程序要求能够完全控制计算机硬件,这也必须使用汇编语言。如操作系统中的低级中断和陷阱处理程序以及许多嵌入式实时系统中的设备控制程序都属于这一类应用。

(4)可以方便地编译

编译器可以产生供编程者使用的汇编程序或者自己执行汇编过程。因此,为了理解编译器的工作原理,必须首先理解汇编语言。

(5)辅助计算机工作者掌握计算机体系结构

研究汇编语言可以使人们清楚实际计算机结构。特别是对于学习计算机体系结构的学生,编写汇编语言是在结构层理解计算机的唯一途径。

(6)程序编制耗时,可读性差

用汇编语言编制程序十分费时,而且程序的质量直接受到程序员技术水平的影响,程序的可读性也很差。就如前面所举的加法计算的例子,用高级语言编程只需写一条加法表达式,简单明了,极其直观。而用汇编语言编程则需写出两条指令,这些指令都是些对硬件的操作,因此程序的可读性很差。

(7)程序可移植性差

由于汇编语言是面向硬件的,所以用汇编语言编制的程序可移植性很差。显而易见,不同的CPU都有相互独立的指令系统,相互间无任何关系,就算是使用同一系列CPU的机器,因其外围硬件可能有差别,这也会使相同的程序在不同的机器上无法通用。

不难看出,汇编语言存在很多的弱点,但由于它具有一些高级语言所不具备的突出优点,所以汇编语言的应用范围还是很广的。特别是当用户需要研究计算机具体的工作原理的时候,还必须要掌握汇编语言。

1.2 进位计数制及其转换

计算机内部的信息分为两大类:控制信息和数据信息。控制信息是一系列的控制命令,用于指挥计算机如何操作;数据信息是计算机操作的对象,一般又可分为数值数据和非数值数据。数值数据用于表示数量的大小,它有确定的数值;非数值数据没有确定的数值,它主要包括字符、汉字和逻辑数据等等。

对计算机而言,不论是控制命令还是数据,它们都要用“0”和“1”两个基本符号即基2码来编码表示,这是由于以下三个原因:

(1)基2码在物理上最容易实现。例如,用高、低两个电位表示“1”和“0”,或用脉冲的有、无表示“1”和“0”,用脉冲的正、负极性表示“1”和“0”等等,可靠性都较高。

(2)基2码用来表示二进制数,其编码及加减运算规则简单。

(3)基2码的两个符号“1”和“0”正好与逻辑数据“真”与“假”相对应,为计算机实现逻辑运算带来了方便。

因此,不论是什么信息,在输入计算机内部时,都必须用基2码编码表示,以方便存储、传送和处理。

1.2.1 数与数制

1.数的表示

进位计数制是一种计数的方法。在日常生活中,人们使用各种进位计数制,如六十进制(1小时=60分,1分=60秒),十二进制(1英尺=12英寸,1年=12月)等。但人们最熟悉和最常用的是十进制计数。按进位的原则进行计数叫进位计数制,简称数制。每种数制都有其基数和各数位的位权。基数是指该数制中允许选用的基本数码的个数。每个数码所表示的数值等于该数码乘以一个与数码所在位置有关的常数,这个常数叫位权,位权的大小是以基数为底,数码所在位置的序号为指数的整数次幂。在汇编语言中常用的进位计数制有:二进制、八进制、十进制和十六进制,其基数、数码和进位关系如表1-1所示。

表1-1几种常用的进位计数制的基数、数码和进位关系

在十进制数中,个位的位权为100,十位的位权为101,百位的位权为102,千位的位权为103,而在小数点后第一位上的位权为10?1,小数点后第二位的位权为10?2等等。因此,如果有十进制数123.45,则百位上的1表示1个100,十位上的2表示2个10,个位上的3表示3个1,小数点后第一位上的4表示4个0.1,小数点后第二位上的5表示5个0.01,用位权表示成:

(123.45)10 =1×102+2×101+3×100+4×10-1+5×10-2

同理,任意一个二进制数、八进制数和十六进制数也可用位权表示。例如:

(101.01)2=1×22+0×21+1×20+0×2-1+1×2-2 (125.46)8 =1×82+2×81+5×80+4×8?1+6×8?2 (AD.5F)16 =A ×161+D ×160+5×16?1+F ×16?2

据上述概念,可推广出表示任意进制数的通式:

N =±i x n

i m

=-∑r i =±(

n i

i x =∑r i +1

m

i

i x -=-∑r i )

其中

n

i

i x

=∑r i 为整数部分,

1

m

i

i x -=-∑r i 为小数部分。r 为基数,每一项的数字可用0~r -1数字

中的一个数字来表示。

2.计数制的书写规则

为了区别不同的计数制,可采用下列两种方法:

(1)在数字后面加写相应的英文字母作为标识,英文字母不分大小写。本书约定采用大写字母形式。如: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表示二进制数的1011 (2DF2)16表示十六进制数的2DF2

1.2.2 不同数制之间的转换

1.十进制数与二进制数之间的转换 (1)十进制整数转换成二进制整数 方法:除2取余法

注意:第一次得到的余数为二进制数的最低位,最后得到的余数为二进制数的最高位。 例1.1 将十进制数97转换成二进制数。其过程如下:

即A 0=1 即A 1=0 即A 2=0 即A 3=0 即A 4=0 即A 5=1 即A 6=1 结束

最后结果为:(97)10 =(A 6 A 5 A 4 A 3 A 2 A 1 A 0)2=(1100001)2 (2)十进制小数转换成二进制小数 方法:乘2取整法

注意:最后将每次得到的整数部分(必定是0或1)按先后顺序从左到右排列即得到所对应二进制小数。

例1.2 将十进制小数0.8125转换成二进制小数。其过程如下:

余数为1, 余数为0, 余数为0, 余数为0, 余数为0, 余数为1, 余数为1, 余数为0

0.8125

× 2

1.6250 整数部分为1,即A?1=1

0.6250 余下的小数部分

× 2

1.2500 整数部分为1,即A?2=1

0.2500 余下的小数部分

× 2

0.5000 整数部分为0,即A?3=0

0.5000 余下的小数部分

× 2

1.0000 整数部分为1,即A?4=1

0.0000 余下的小数部分为0,结束

最后结果为:(0.8125)10=(0.A?1A?2A?3A?4) 2 =(0.1101)2

(3)一般的十进制数转换成二进制数

为了将一个既有整数又有小数部分的十进制数转换成二进制数,可以将其整数部分和小数部分分别进行转换,然后再组合起来。

例1.3 将(97.8125)10转换成二进制数。其过程如下:

(97)10=(1100001)2

(0.8125)

=(0.1101)2

10

由此可得:(97.8125)10 =(1100001.1101)2

(4)二进制数转换十进制数

方法:按位权展开后相加。

注意:用其各位所对应的系数,按“位权展开求和”的方法就可以得到,其基数为2。

例1.4 将(101.11)2转换成十进制数。其过程如下:

(101.11)2=1×22+0×21+1×20+1×2?1+1×2?2

=4+0+1+0.5+0.25

=(5.75)10

2.十进制与八进制之间的转换

(1)十进制整数转换成八进制整数

方法:除8取余法。

注意:采用基数8连续去除该十进制整数,直至商等于“0”为止,然后逆序排列所得到的余数。

例1.5 将十进制数97转换成八进制数。其过程如下:

8 ︳97 余数为1,即A0=1

8 ︳12 余数为4,即A1=4

8 ︳1 余数为1,即A2=1

0 余数为0,结束

最后结果为:(97)10=(A2 A1 A0) 8=(141)8

(2)十进制小数转换成八进制小数

方法:乘8取整法。

注意:连续用基数8去乘以该十进制小数,直至乘积的小数部分等于“0”,然后顺序排列每次乘积的整数部分。

例1.6 将十进制小数0.6875转换成八进制小数。其过程如下:

0.6875

×8

5000 整数部分为5,即A?1=5

0.5000 余下的小数部分

×8

4.0000 整数部分为4,即A?2=4

0.0000 余下的小数部分为0,结束

最后结果为:(0.6875)10 =(0.A?1A?2)8=(0.54)8(3)八进制数转换成十进制数

方法:按位权展开后相加。

用其各位所对应的系数,按“位权展开求和”的方法就可以得到,其基数为8。

例1.7将(141.54)8转换为十进制数。其过程如下:

(141.54)8=1×82+4×81+1×80+5×8?1+4×8?2

=64+32+1+0.625+0.0625

=97.6875

最后结果为:(141.54)8 =(97.6875)10

3.十进制与十六进制之间的转换

(1)十进制整数转换成十六进制整数

方法:除16取余法。

注意:采用基数16连续去除该十进制整数,直至商等于“0”为止,然后逆序排列所得到的余数。

例1.8 将十进制整数(2347)10转换为十六进制整数,采用“除16倒取余”的方法,过程如下:

16 ︳2347 余数为11,即A0=B(十六进制数为B)

16 ︳146 余数为2,即A1=2

16 ︳9 余数为9,即A2=9

0 余数为0,结束

最后结果为:(2347)10=(A2 A1 A0)16=(92B)16

(2) 十进制小数转换成十六进制小数

方法:乘16取整法。

注意:连续用基数16去乘以该十进制小数,直至乘积的小数部分等于“0”,然后顺序排列每次乘积的整数部分。

例1.9将十进制小数0.6875转换成十六进制小数。其过程如下:

0.6875

×16

11.0000 整数部分为11,即A?1=B

0.0000 余下的小数部分为0,结束

最后结果为:(0.6875)10 =(0.A?1)16 =(0.B)16

(3)十六进制数转换十进制数

方法:按位权展开后相加。

注意:用其各位所对应的系数,按“位权展开求和”的方法就可以得到,其基数为16。

例1.10将(92B.B)16转换成十进制数。其过程如下:

(92B.B)16=9×162+2×161+B×160+B×16?1

=9×162+2×161+11×160+11×16?1

=2347.6875

最后结果为:(92B.B)16=(2347.6875)10

4.二进制与八进制、十六进制数之间的转换

因为:23=8,所以每三位二进制数对应一位八进制数;

24=16,所以每四位二进制数对应一位十六进制。

表1-2列出了十进制、二进制、八进制、十六进制最基本的数字的对应关系。这些对应关系在后面的二进制、八进制、十六进制相互转换中要经常用到。

(1)二进制数转换成八进制数

从小数点所在位置分别向左向右每三位一组进行划分。若小数点左侧的位数不是3的整数倍,在数的最左侧补零;若小数点右侧的位数不是3的整数倍,在数的最右侧补零。然后参照表1-2,将每三位二进制数转换成对应的一位八进制数,即为二进制数对应的八进制数。

表1-2十、二、八、十六进制数码的对应关系

例1.11将(11010.11)2转换为八进制数。其过程如下:

011 010 . 110

3 2. 6

所以(11110.11)2 =(32.6)8

(2)八进制数转换成二进制数

方法:参照表1-2,将每一位八进制数转换成对应的三位二进制数,即为八进制数对应的二进制数。

例1.12将(34.6)8转换为二进制数。其过程如下:

3 4. 6

011 100. 110

所以(34.6)8=(11100.11)2

(3)二进制数转换成十六进制数

从小数点所在位置分别向左向右每四位一组进行划分。若小数点左侧的位数不是4的整数倍,在数的最左侧补零;若小数点右侧的位数不是4的整数倍,在数的最右侧补零。然后参照表1-2,将每四位二进制数转换成对应的一位十六进制数,即为二进制数对应的十六进制数。

例1.13将(1011110.11)2转换为十六进制数。其过程如下:

0101 1110 .1100

5 E . C

所以(1011110.11)2=(5E.C) 16

(4) 十六进制数转换成二进制数

方法:参照表1-2,将每一位十六进制数转换成对应的四位二进制数,即为十六进制数对应的二进制数。

例1.14将(E8.C) 16转换为二进制数。其过程如下:

E 8 C

1110 1000 1100

所以(E8.C) 16=(11101000.11)2

八进制数和十六进制数主要用来简化二进制数的书写,因为具有23=8,24=16的关系,故使用八进制数和十六进制数表示的二进制数较短,便于记忆。IBM–PC机中主要使用十六进制数表示二进制数和编码,所以必须十分熟悉二进制数与十六进制数的对应关系。

1.3计算机中数与字符的表示方法

计算机中数值型数据是用二进制数来表示的,而非数值型数据包括英文字母、标点符号、专用符号、汉字等,也是用二进制数来编码的。

1.3.1 数值型数据的编码

1. 二进制数的编码及运算

我们很容易想到,数据的正负号可用一位二进制的0和1两个状态来表示,这样,二进制数值数据在计算机中就能方便表示了。为了尽可能地简化对二进制数值数据进行算术运算用到的规则,机器将二进制数值数据进行编码表示。

常用的编码有原码、反码和补码。由于补码编码有许多优点,大多数微机采用了补码编

码,所以我们着重介绍补码编码表示法。

为了讨论方便,有必要引入两个概念:机器数和机器数的真值。

●机器数:带符号的二进制数值数据在计算机内部的编码。

●真值:机器数所代表的实际值。

一般机器数的最高有效位用来表示数的正负符号,0表示正数,1表示负数。

(1)二进制数原码编码

正数的符号位为0,负数的符号位为1,其它位按照一般的方法来表示数的绝对值。用这样的表示方法得到的就是数的原码。

例1.15当机器字长为8位二进制数时:

X=+1011011 [X]原码=01011011

Y=-1011011 [Y]原码=11011011

[+1]原码=00000001 [-1]原码=10000001

[+127]原码=01111111 [-127]原码=11111111 原码表示的整数范围是:

-(2n-1-1)~+(2n-1-1),其中n为机器字长。

则:8位二进制原码表示的整数范围是-127~+127,16位二进制原码表示的整数范围是-32767~+32767。

(2)二进制数反码编码

对于一个带符号的数来说,正数的反码与其原码相同,负数的反码为其原码除符号位以

外的各位按位取反。

例1.16当机器字长为8位二进制数时:

X=+1011011 [X]原码=01011011 [X]反码=01011011

Y=-1011011 [Y]原码=11011011 [Y]反码=10100100

[+1]反码=00000001 [-1]反码=11111110

[+127]反码=01111111 [-127]反码=10000000

负数的反码与负数的原码有很大的区别,反码通常用作求补码过程中的中间形式。反码表示的整数范围与原码相同。

(3)二进制数补码编码

正数的补码与其原码相同,负数的补码为其反码在最低位加1。

例1.17当机器字长为8位二进制数时,求X和Y的补码。

(a)X=+1011011B (b)Y=-1011011B

(a)根据定义有:[X]原码=0 101 1011 [X]补码=0 101 1011

(b)根据定义有:[Y]原码=1 101 1011 [Y]反码=1 010 0100

[Y]补码=1 010 0101

例1.18机器字长n=8位,X=+48D,求[X]补码。

将+48D转换为二进制:+110000B。

因为机器字长是8位,其中符号占了1位,所以数值只占7位。

则:[X]原码=0 011 0000,[X]补码= 0 011 0000。如写成十六进制,即[X]补码=30H。

例1.19机器字长n=8位,X=?48D,求[X]补码。

将?48D转换为二进制:?110000B。

因为机器字长是8位,其中符号占了1位,所以数值只占7位。

则:[X]原码=1 011 0000,[X]反码=1 100 1111,[X]补码=1 101 0000。如写成十六进制,即[X]补码=0D0H。

例1.20当机器字长为16位二进制数时,X=+48D,求[X]补。

将+48D转换为二进制:+110000B。

因为机器字长是16位,其中符号占了1位,所以数值只占15位。

则:[X]原码=0 000 0000 0011 0000,[X]补码= 0 000 0000 0011 0000。如写成十六进制,即[X]补码=0030H。

例1.21当机器字长为16位二进制数时,X=?48D,求[X]补。

将?48D转换为二进制:?110000B。

因为机器字长是16位,其中符号占了1位,所以数值只占15位。

则:[X]原码=1 000 0000 0011 0000,[X]反码=1 111 1111 1100 1111,[X]补码= 1 111 1111 1101 0000。

如写成十六进制,即[X]补码=0FFD0H。

由此可看出,补码数要扩展时,正数是在符号的前面补0,负数是在符号的前面补1。也就是说,补码数扩展实际上是符号扩展。

已知补码求真值的方法是:当机器数的最高位(符号位)为0时,表示真值是正数,其

值等于其余n?1位的值;当机器数的最高位(符号位)为1时,表示真值是负数,其值等于其余n?1位按位取反末位加1的值。

例1.22(a)[X]补码=01011001B,(b)[X]补码=11011001B,分别求其真值X。

(a)[X]补码代表的数是正数,其真值:

X=+1011001B

=+(1×26+1×24+1×23+1×20)

=+(64+16+8+1)

=+(89)D

(b)[X]补码代表的数是负数,则真值:

X=-([1011001]求反+1)B

=-(0100110+1)B

=-(0100111)B

=-(1×25+1×22+1×21+1×20)

=-(32+4+2+1)

=-(39)D

下面,我们来讨论一下补码表示数的范围。

一般来说,如果机器字长为n位,则补码能表示的整数范围是:

?2n?1≤N≤2n?1?1

例如,当n=8时,?128≤N≤+127,其二进制补码数范围如表1-3所示。

相关主题
文本预览
相关文档 最新文档