《经典汇编教学.doc》由会员分享,可在线阅读,更多相关《经典汇编教学.doc(199页珍藏版)》请在taowenge.com淘文阁网|工程机械CAD图纸|机械工程制图|CAD装配图下载|SolidWorks_CaTia_CAD_UG_PROE_设计图分享下载上搜索。
1、经典汇编语言程序设计第1章汇编语言的由来,数据类型本章介绍汇编语言的一些基本概念,给出一些用汇编语言编程所需要的基本知识。1.1 汇编语言的由来及其特点1.1.1 机器语言机器指令是CPU能直接识别并执行的指令,它的表现形式是二进制编码。机器指令通常由操作码和操作数两部分组成,操作码指出该指令所要完成的操作,即指令的功能,操作数指出参与运算的对象,以及运算结果所存放的位置等。由于机器指令与CPU紧密相关,所以,不同种类的CPU所对应的机器指令也就不同,而且它们的指令系统往往相差很大。但对同一系列的CPU来说,为了满足各型号之间具有良好的兼容性,要做到:新一代CPU的指令系统必须包括先前同系列C
2、PU的指令系统。只有这样,先前开发出来的各类程序在新一代CPU上才能正常运行。机器语言是用来直接描述机器指令、使用机器指令的规则等。它是CPU能直接识别的唯一一种语言,也就是说,CPU能直接执行用机器语言描述的程序。用机器语言编写程序是早期经过严格训练的专业技术人员的工作,普通的程序员一般难以胜任,而且用机器语言编写的程序不易读、出错率高、难以维护,也不能直观地反映用计算机解决问题的基本思路。由于用机器语言编写程序有以上诸多的不便,现在几乎没有程序员这样编写程序了。1.1.2汇编语言虽然用机器语言编写程序有很高的要求和许多不便,但编写出来的程序执行效率高,CPU严格按照程序员的要求去做,没有多
3、余的额外操作。所以,在保留“程序执行效率高”的前提下,人们就开始着手研究一种能大大改善程序可读性的编程方法。为了改善机器指令的可读性,选用了一些能反映机器指令功能的单词或词组来代表该机器指令,而不再关心机器指令的具体二进制编码。与此同时,也把CPU内部的各种资源符号化,使用该符号名也等于引用了该具体的物理资源。如此一来,令人难懂的二进制机器指令就可以用通俗易懂的、具有一定含义的符号指令来表示了,于是,汇编语言就有了雏型。现在,我们称这些具有一定含义的符号为助忆符,用指令助忆符、符号地址等组成的符号指令称为汇编格式指令(或汇编指令)。汇编语言是汇编指令集、伪指令集和使用它们规则的统称。伪指令是在
4、程序设计时所需要的一些辅助性说明指令,它不对应具体的机器指令,有关内容在以后的各章节中会有详细叙述,在此不展开介绍。用汇编语言编写的程序称为汇编语言程序,或汇编语言源程序,在本教材中或特定的环境下,也可简称为源程序。汇编语言程序要比用机器指令编写的程序容易理解和维护。1.1.3汇编程序用汇编语言编写的程序大大提高了程序的可读性,但失去了CPU能直接识别的特性。例如用汇编语言书写的指令:MOV AX,BX,CPU不会知道这几个字符所表达出来的功能,但程序员一看就知道:要求CPU把寄存器BX的值传送给寄存器AX。把机器指令符号化增加了程序的可读性,但引起了如何让CPU知道程序员的用意,并按照其要求
5、完成相应操作的问题。解决该问题就需要一个翻译程序,它能把汇编语言编写的源程序翻译成CPU能识别的机器指令序列。这里,我们称该翻译程序为汇编程序。 图1.1是汇编程序翻译过程的示意图。从图中不难看出:汇编程序能把左边汇编语言源程序翻译成右边的机器指令序列。其中,把汇编语言指令“MOV AX, BX”和“ADD AX,5”分别转换成机器指令89D8H和050500H,而后者都是CPU能直接识别的,所以,可执行它们。目前,常用的汇编程序有:MASM、TASM和DEBUG等。1.1.4 汇编语言的特点 一方面,汇编语言指令是用一些具有相应含义的助忆符来表达的,所以,它要比机器语言容易掌握和运用,但另一
6、方面,它要直接使用CPU的资源,相对高级程序设计语言来说,它又显得难掌握。汇编语言程序归纳起来大概有以下几个主要特性。1、与机器相关性汇编语言指令是机器指令的一种符号表示,而不同类型的CPU有不同的机器指令系统,也就有不同的汇编语言,所以,汇编语言程序与机器有着密切的关系。由于汇编语言程序与机器的相关性,所以,除了同系列、不同型号CPU之间的汇编语言程序有一定程度的可移植性之外,其它不同类型(如:小型机和微机等)CPU之间的汇编语言程序是无法移植的,也就是说,汇编语言程序的通用性和可移植性要比高级语言程序低。2、执行的高效率正因为汇编语言有“与机器相关性”的特性,程序员用汇编语言编写程序时,可
7、充分发挥自己的聪明才智,对机器内部的各种资源进行合理的安排,让它们始终处于最佳的使用状态,这样做的最终效果就是:程序的执行代码短,执行速度快。现在,高级语言的编译程序在进行寄存器分配和目标代码生成时,也都有一定程度的优化(在后续课程编译原理的有关章节会有详细介绍),但由于所使用的“优化策略”要适应各种不同的情况,所以,这些优化策略只能在宏观上,不可能在微观上、细节上进行优化。而用汇编语言编写程序几乎是程序员直接在写执行代码,程序员可以在程序的每个具体细节上进行优化,这也是汇编语言程序执行高效率的原因之一。3、编写程序的复杂性汇编语言是一种面向机器的语言,其汇编指令与机器指令基本上一一对应,所以
8、,汇编指令也同机器指令一样具有功能单一、具体的特点。要想完成某件工作(如计算:A+B+C等),就必须安排CPU的每步工作(如:先计算A+B,再把C加到前者的结果上)。另外,在编写汇编语言程序时,还要考虑机器资源的限制、汇编指令的细节和限制等等。由于汇编语言程序要安排运算的每一个细节,这就使得编写汇编语言程序比较繁琐、复杂。一个简单的计算公式或计算方法,也要用一系列汇编指令一步一步来实现。4、调试的复杂性在通常情况下,调试汇编语言程序要比调试高级语言程序困难,其主要原因有四: 汇编语言指令涉及到机器资源的细节,在调试过程中,要清楚每个资源的变化情况;程序员在编写汇编语言程序时,为了提高资源的利用
9、率,可以使用各种实现技巧,而这些技巧完全有可能破坏程序的可读性。这样,在调试过程中,除了要知道每条指令的执行功能,还要清楚它在整个解题过程中的作用;高级语言程序几乎不显式地使用“转移语句”,但汇编语言程序要用到大量的、各类转移指令,这些跳转指令大大地增加了调试程序的难度。如果在汇编语言程序中也强调不使用“转移指令”,那么,汇编语言程序就会变成功能单调的顺序程序,这显然是不现实的;调试工具落后,高级语言程序可以在源程序级进行符号跟踪,而汇编语言程序只能跟踪机器指令。不过,现在这方面也有所改善,CV(CodeView)、TD(Turbo Debug)等软件也可在源程序级进行符号跟踪了。1.1.5
10、汇编语言的应用领域 综上所说,汇编语言的特点明显,其诱人的优点直接导致其严重的缺点,其“与机器相关”和“执行的高效率”导致其可移植性差和调试难。所以,我们在选用汇编语言时要根据实际的应用环境,尽可能避免其缺点对整个应用系统的影响。下面简单列举几个领域以示说明,但不要把它们绝对化。1、适用的领域要求执行效率高、反应快的领域,如:操作系统内核,工业控制,实时系统等;系统性能的瓶颈,或频繁被使用子程序或程序段;与硬件资源密切相关的软件开发,如:设备驱动程序等;受存储容量限制的应用领域,如:家用电器的计算机控制功能等;没有适当的高级语言开发环境。2、不宜使用的领域 大型软件的整体开发;没有特殊要求的一
11、般应用系统的开发等。1.2 数据地表示和类型 在用汇编语言进行程序设计时,程序员可以直接访问内存,对数据在存储器内的表示形式要有一个清晰的认识。下面,我们只简单介绍本课程所要用到的数据表示知识,为后面的学习作一点必要的准备。 有关“数据表示”的详细内容请参阅计算机组成原理中的相关章节。1.2.1 数值数据的表示(1)、二进制在计算机内,数值是用二进制来表示的,每个二进制数按权相加就可得到其十进制数值。在书写二进制时,为了区别,在数据后面紧跟一个字母B。二进制的一般表现形式为:bn-1b1b0B,其代表数值:bn-12n-1+b121+b020。数据的二进制表示形式简单、明了,但它书写起来比较长
12、,所以,通常情况下,我们在程序中不直接用二进制来书写具体的数值,而改用八进制、十进制或十六进制。(2)、八进制八进制是一种二进制的变形,三位二进制可变为一位八进制,反之也然。八进制的表示元素是:0、1、7。在书写时,为了区别,在数据后面紧跟一个字母Q。如:1234Q、7654Q、54Q等都是八进制。八进制数在程序中的使用频率不高。(3)、十进制十进制是我们最熟悉的一种数据表示形式,它的基本元素是:0、1、9。在书写时,为了区别,在数据后面紧跟一个字母D。在程序中经常用十进制来表示数据。(4)、十六进制十六进制是另一种二进制的变形,四位二进制可变为一位十六进制,反之也然。十六进制的基本元素是:0
13、、1、9、A、B、F(字母小写也可以),其中:字母A、B、F依次代表10、11、15。在书写时,为了区别,在数据后面紧跟一个字母H。当十六进制数的第一个字符是字母时,在第一个字符之前必须添加一个0。如:100H、56EFH、0FFH、0ABCDH等都是十六进制数。十六进制在程序中的使用频率很高。(5)、数值进制的总结和相互转换表1.1 各种进制及其字符表示进制字符例子备注二进制B/Y(*)1010B、1011B(*):字符Y、O和T是宏汇编MASM系统所增加的进制表示符。 八进制Q/O1234Q、311Q十进制D/T1234D、512D十六进制H1234H、1011H1.2.1 数值表示及其扩
14、展 在计算机内,为了表示正负数,并便于进行各种算术运算,对有符号数采用二进制的补码表示形式。补码的最高位用来表示正负数:0正数,1负数。正数的补码是其自身的二进制形式,负数的补码是把其正数的二进制编码变“反”,再加1而得。(7)、二进制数的符号扩展在汇编语言中,我们经常要对字/字节的数据进行操作。当把“字节”转换成“字”,或“字”转换成“双字”时,就需要进行符号扩展。符号扩展的具体操作就是把已知信息的最高位扩展到所有更高位。例1.1 把8位补码01011010、10101100分别扩展成16位补码。解:根据符号扩展的含义,“字节字”的具体扩展结果如下:010110101010110000000
15、000010110101111111110101100例1.2 把16位补码0101101111001010、1010111101011011别扩展成32位补码。解:根据符号扩展的含义,“字双字”的具体扩展结果如下:010110111100101010101111010110110000000000000000010110111100101011111111111111111010111101011011(8)、n位二进制的表示范围n位二进制所能表示的无符号整数的范围:0x2n-1。n位二进制所能表示的有符号整数(补码表示)的范围:-2n-1x2n-1-1。在汇编语言中,常用到n为8和16时的
16、数值范围:n=8时,无符号整数的范围:0255,有符号整数的范围:-128127;n=16时,无符号整数的范围:065535,有符号整数的范围:-3276832767。(9)、BCD码通常,我们习惯用十进制表示的数据,但计算机是用二进制来表示数数据的,这就需要进行数值进制之间的转换。我们把每位十进制数转换二进制的编码,简称为BCD码(BinaryCoded Decimal)。BCD码是用4位二进制编码来表示1位十进制数。这种编码方法有多种,但常用的编码是8421BCD编码,如表1.2所示。这种BCD编码实际上就是09的“等值”二进制数。表1.2 8421BCD编码列表十进制数字8421BCD码
17、十进制数字8421BCD码00000501011000160110200107011130011810004010091001用BCD码进行进制的转换时,是要求在二种进制的表现形式上快速转换,而不是要求在“数值相等”的含义快速转换。例1.3 求十进制数2000的BCD编码和其二进制数。解:2000的BCD编码是把每位上的数2、0、0、0分别转换为其对应的BCD编码:0010、0000、0000和0000,把它们合在一起就是2000的BCD编码:00100000 0000 0000。十进制数2000的二进制数是:11111010000,它们在数值上是相等的。1.2.2 非数值数据的表示 计算机除
18、了具有进行数值计算能力之外,还具有进行非数值计算的能力。现在,后者的应用领域已远远超过了前者的应用领域,如:文字处理、图形图象处理、信息检索、日常的办公管理等。所以,对非数值信息的编码就显得越加重要。1、ASCII码ASCII码(American Standard Code for Information Interchange)是目前应用极其广泛的一种信息编码,许多计算机系统都是采用它为字符进行编码。它是一种7位二进制编码。右表是ASCII码的具体编码方案。在该表中,对学习本课程有用的主要信息有:字符09是连续编码的,其编码的低4位就是该字符在十进制中的数值;小写字母的编码比大写字母的编码大
19、,对应字母的编码之间相差20H。 当然,从ASCII码表中还可看出其它有用信息,还有扩展的ASCII码等知识,但这些内容对学习本课程的帮助不明显,故不再叙述。有兴趣的读者可参阅其它书籍。表1.3 ASCII码的编码方案高位低位0000010100111001011101110000NULDELSP0Pp0001SOHDC1!1AQaq0010STXDC2“2BRbr0011ETXDC3#3CScs0100EOTDC4$4DTdt0101ENQNAK%5EUeu0110ACKSYN&6FVfv0111BELETB7GWgw1000BSCAN(8HXhx1001HTEM)9IYiy1010LFSU
20、B*:JZjz1011VTESC+;Kk1100FFFSNn1111SIUS/?O_oDel2、汉字编码ASCII码是针对英文的字母、数字和其它特殊字符进行编码的,它不能用于对汉字的编码。要想用计算机来处理汉字,就必须先对汉字进行适当的编码。我国在1981年5月对6000多个常用的汉字制定了交换码的国家标准,即:GB2312-80。该标准规定了汉字交换用的基本汉字字符和一些图形字符,它们共计7445个,其中汉字有6763个。该标准给定每个字符的二进制编码,即国标码。1.2.3 基本的数据类型内容正文汇编语言所用到的基本数据类型为:字节、字、双字等,这些数据类型在以后的章节中都有相应的类型说明符
21、。下面对它们进行最基本的描述。1、 字节一个字节有8位二进制组成,其最高位是第7位,最低位是第0位,如右图所示。在表示有符号数时,最高位就是符号位。通常情况下,存储器按字节编址,读写存储器的最小信息单位就是一个字节。2、 字 图1.2 字节数据类型示意图3、 由2个字节组成一个字,其最高位是第15位,最低位是第0位。高8位称为 高字节,低8位称为低字节,如右图所示。字节和字是汇编语言程序中最常用的两种数据类型,也是最容易出错的数据类型。4、 双字用2个字(4个字节)来组成一个双字,其高16位称为高字,低16位称为低字, 图1.3 字数据类型示意图。如右图所示。双字有较大的数据表示范围,它通常是
22、为了满足数据的表示范围而选用的数据类型,也可用于存储远指针。字节、字和双字是汇编语言最常用的三种数据类型,下图表现出它们三者之间的组成关系。5、字符串字符串是由若干个字节组成的,字节数不定,通常每个字节存储一个字符。该数据形式是汇编语言程序中经常使用的另一种数据形式。1.3 习题1.1、汇编语言的主要特点有哪些?1.2、汇编语言适用于哪些领域,在哪些领域使用不太方便?1.3、在汇编语言中,如何表示二进制、八进制、十进制和十六进制的数值?1.4、在计算机中,如何表示正、负数?在保持数值大小不变的情况下,如何把位数少的二进制数值扩展成位数较多的二进制数值?1.5、在ASCII表,字符09与数值09
23、之间编码规律是什么?大写字母和小写字母之间的编码规律是什么?1.6、汇编语言中的基本数据类型有哪些?它与高级程序设计语言(如:C语言)中的数据类型的对应关系是什么?第2章 CPU资源和存储器计算机的硬件资源是用汇编语言编程所必须要了解的重要内容,因为汇编语言允许、也需要程序员直接使用这些硬件资源,只有这样才能编写出高效的目标代码。在汇编语言中,需要访问的硬件资源主要有:CPU内部资源、存储器和I/O端口。本章将着重讲解CPU内部寄存器的命名、功能及其常见的用途,还要介绍存储器的分段管理模式、存储单元地址的表示法以及其物理地址的形成方式。2.1 寄存器组寄存器是CPU内部重要的数据存储资源,是汇
24、编程序员能直接使用的硬件资源之一。由于寄存器的存取速度比内存快,所以,在用汇编语言编写程序时,要尽可能充分利用寄存器的存储功能。寄存器一般用来保存程序的中间结果,为随后的指令快速提供操作数,从而避免把中间结果存入内存,再读取内存的操作。在高级语言(如:C/C+语言)中,也有定义变量为寄存器类型的,这就是提高寄存器利用率的一种可行的方法。另外,由于寄存器的个数和容量都有限,不可能把所有中间结果都存储在寄存器中,所以,要对寄存器进行适当的调度。根据指令的要求,如何安排适当的寄存器,避免操作数过多的传送操作是一项细致而又周密的工作。有关“寄存器的分配策略”在后续课程编译原理中会有详细的介绍。由于16
25、位/32位CPU是微机CPU的两个重要代表,所以,在此只介绍它们内部寄存器的名称及其主要功能。2.1.1 寄存器组1、 16位寄存器组16位CPU所含有的寄存器有(见图2.1中16位寄存器部分):4个数据寄存器(AX、BX、CX和DX)2个变址和指针寄存器(SI和DI)2个指针寄存器(SP和BP)4个段寄存器(ES、CS、SS和DS)1个指令指针寄存器(IP)1个标志寄存器(Flags)2、 32位寄存器组32位CPU除了包含了先前CPU的所有寄存器,并把通用寄存器、指令指针和标志寄存器从16位扩充成32位之外,还增加了2个16位的段寄存器:FS和GS。32位CPU所含有的寄存器有(见图2.1
26、中的寄存器):4个数据寄存器(EAX、EBX、ECX和EDX)2个变址和指针寄存器(ESI和EDI)2个指针寄存器(ESP和EBP)6个段寄存器(ES、CS、SS、DS、FS和GS)1个指令指针寄存器(EIP)1个标志寄存器(EFlags)图2.1 CPU寄存器组的示意图2.1.1 存储器组通用寄存器可用于传送和暂存数据,也可参与算术逻辑运算,并保存运算结果。除此之外,它们还各自具有一些特殊功能。汇编语言程序员必须熟悉每个寄存器的一般用途和特殊用途,只有这样,才能在程序中做到正确、合理地使用它们。表2.1 通用寄存器的主要用途寄存器的分类寄存器主 要 用 途通 用寄 存 器数据 寄存器AX乘、
27、除运算,字的输入输出,中间结果的缓存AL字节的乘、除运算,字节的输入输出,十进制算术运算AH字节的乘、除运算,存放中断的功能号BX存储器指针CX串操作、循环控制的计数器CL移位操作的计数器DX字的乘、除运算,间接的输入输出变址寄存器SI存储器指针、串指令中的源操作数指针DI存储器指针、串指令中的目的操作数指针变址寄存器BP存储器指针、存取堆栈的指针SP堆栈的栈顶指针指令指针 IP/EIP标志位寄存器Flag/EFlag32位 CPU的段寄存器16位CPU的 段寄存器ES附加段寄存器CS代码段寄存器SS堆栈段寄存器DS数据段寄存器新增加的段寄存器FS附加段寄存器GS附加段寄存器2.1.2 程序状
28、态字16位CPU内部有一个16位的标志寄存器,它包含9个标志位。这些标志位主要用来反映处理器的状态和运算结果的某些特征。各标志位在标志寄存器内的分布如图2.2所示。1514131211109876543210OFDFIFTFSFZFAFPFCF3117161514131211109876543210VMRFNTIOPLOFDFIFTFSFZFAFPFCF图2.2 16位/32位标志寄存器的示意图上面9个标志位可分为二组:运算结果标志位(有背景色的标志位)和状态控制标志位。前者受算术运算和逻辑运算结果的影响,后者受一些控制指令执行的影响。更详细的内容请点击:标志位的说明。有些指令的执行会改变标志
29、位(如:算术运算指令等),不同的指令会影响不同的标志位,有些指令的执行不改变任何标志位(如:MOV指令等),有些指令的执行会受标志位的影响(如:条件转移指令等),也有指令的执行不受其影响。程序员要想熟练运用这些标志位,就必须掌握每个标志位的含义、每条指令的执行条件和执行结果对标志位的作用。注意:虽然知道每个标志位在标志寄存器内的具体位置是有好处的,但通常情况下,没有这个必要。在使用第5.2.9节中的“条件转移指令”时,系统会自动引用相应标志位的值来决定是否需要“转移”的,所以,不必过分强调标志位在标志寄存器内的具体位置。2.2 16位微机存储器的管理模式Intel公司的80X86系列的CPU基
30、本上采用内存分段的管理模式。它把内存和程序分成若干个段,每个段的起点用一个段寄存器来记忆,所以,学习微机汇编语言,必须要清楚地理解存储器的分段含义、存储单元的逻辑地址和其物理地址之间的转换关系。2.2.1 16位微机的内存管理模式1、存储器的分段我们知道:计算机的内存单元是以“字节”为最小单位进行线性编址的。为了标识每个存储单元,就给每个存储单元规定一个编号,此编号就是该存储单元的物理地址。存储单元的物理地址是一个无符号的二进制数。但为了书写的简化,物理地址通常用十六进制来表示。16位CPU内部有20根地址线,其编码区间为:00000H0FFFFFH,所以,它可直接访问的物理空间为1M(220
31、)字节。而16位CPU内部存放存储单元偏移量的寄存器(如:IP、SP、BP、SI、DI和BX等)都是16位,它们的编码范围仅为:00000H0FFFFH。这样,如果用16位寄存器来访问内存的话,则只能访问内存的最低端的64K,其它的内存将无法访问。为了能用16位寄存器来有效地访问1M的存储空间,16位CPU采用了内存分段的管理模式,并引用段寄存器的概念。16位微机把内存空间划分成若干个逻辑段,每个逻辑段的要求如下:图2.4 16位微机内存分段管理示意图逻辑段的起始地址(通常简称为:段地址)必须是16的倍数,即最低4位二进制必须全为0;逻辑段的最大容量为64K,这由16位寄存器的寻址空间所决定。
32、按上述规定,1M内存最多可分成64K个段,即65536个段(段之间相互重叠),至少可分成16个相互不重叠的段。 右图2.4是内存各逻辑段之间的分布情况示意图,其中有相连的段(如:C和D段)、不相连的段(如:A和B段)以及相互重叠的段(如:B和C段)。这种存储器分段的内存管理方法不仅实现了用两个16位寄存器来访问1M的内存空间,而且对程序的重定位、浮动地址的编码和提高内存的利用率等方面都具有重要的实用价值。 2.2.1 物理地址的形成方式由于规定段地址必须是16的倍数,所以,其值的一般形式为:XXXX0H,即:前16位二进制位是变化的,后四位是固定为0。鉴于段地址的这种特性,我们可以仅保存其前1
33、6位二进制来达到保存整个段地址,其后四位可通过“左移补0”来获得。在确定了某个存储单元所属的内存段后,我们也只知道其所处内存位置的范围,还不能确定其具体位置。要想确定内存单元的具体位置,还必须知道该单元离该段地址有多远。我们通常把存储单元的实际地址与其所在段的段地址之间的距离称为段内偏移,也可称为有效地址(EAEffectiveAddress)或偏移量(Offset)等。有了段地址和偏移量,就能唯一地确定某一内存单元在存储器内的具体位置。由此可见,存储单元的逻辑地址分为两部分:段地址和偏移量。由逻辑地址得到其物理地址(PAPhysicalAddress)的计算方法如下:物理地址PA=段地址16
34、 + 偏移量计算存储单元物理地址的公式可用“左移4位”和“加”运算来实现。图2.5是物理地址的计算示意图。图2.5 16位CPU物理地址计算示意图图2.6 物理地址和逻辑地址之间的关系对物理地址来说,当段地址变化时,只要对其偏移量进行相应的调整就可对应同一个物理地址,所以,同一个物理地址可有多个逻辑地址。如图2.6所示。在汇编语言程序中,存储单元通常不是用其物理地址标识的,而是用其逻辑地址标识的。逻辑地址的段地址由段寄存器给出,偏移量可由寄存器(SI、DI、BP和BX等)给出,也可用符号地址或具体的数值给出。至于在指令中如何指出存储单元的逻辑地址将在第3章“寻址方式”中给出详细说明。1 段寄存
35、器的引用段寄存器是因为对内存的分段管理而设置的。16位CPU有四个段寄存器,所以,其程序可同时访问四个不同含义的段。段寄存器及其偏移量的引用关系如图2.7所示。段寄存器CS指向存放程序的内存段,IP是用来存放下条待执行的指令在该段的偏移量,把它们合在一起可在该内存段内取到下次要执行的指令。段寄存器SS指向用于堆栈的内存段,SP是用来指向该堆栈的栈顶,把它们合在一起可访问栈顶单元。另外,当偏移量用到了指针寄存器BP,则其缺省的段寄存器也是SS,并且用BP可访问整个堆栈,不仅仅是只访问栈顶。段寄存器DS指向数据段,ES指向附加段,在存取操作数时,二者之一和一个偏移量合并就可得到存储单元的物理地址。
36、该偏移量可以是具体数值、符号地址和指针寄存器的值等之一,具体情况将由指令的寻址方式 图2.7段和段寄存器的引用示意图来决定。通常,缺省的数据段寄存器是DS,只有一个例外,即:在进行串操作时,其目的地址的段寄存器规定为ES。当然,在一般指令中,我们还可以用强置前缀的方法来改变操作数的段寄存器(见:第3.3节中的强置前缀的书写格式)。一般情况下,段寄存器及其指针寄存器的引用关系如下表所示。表2.2中的“可选用的段寄存器”即是可以用强置说明这些段寄存器的值来作为其操作数地址的段地址。表2.2 段寄存器及其指针寄存器的引用关系访问存储器方式缺省的段寄存器可选用的段寄存器偏移量取指令CSIP堆栈操作SS
37、SP一般取操作数DSCS、ES、SS有效地址串操作源操作数DSCS、ES、SSSI目标操作数ESDI使用指针寄存器BPSSCS、DS、ES有效地址由上表可以看出16位CPU在段寄存器的引用方面有如下规定:、取指令所用的段寄存器和偏移量一定是用CS和IP;、堆栈操作所用的段寄存器和偏移量一定是SS和SP;、串操作的目标操作数所用的段寄存器和偏移量一定是ES和DI;、其它情况,段寄存器除了其默认引用的寄存器外,还可以强行改变为其它段寄存器。对于上述规定,随着后续内容的叙述,将会对它们有更进一步理解。2 存储单元的内容上面,我们讲述了16位微机的内存管理及其相关知识,知道了内存单元物理地址的计算方法
38、,这使我们能很容易地指定所要访问的存储单元。但存储单元里的内容是如何存放的呢?下面就能描述数值在内存的存放形式。存储单元中所存放的二进制信息通常称为该存储单元的内容或值,并且规定:一个字节的内容是该字节单元内存放的二进制信息;一个字的内容是该字地址所指向的单元及其后继一个单元的内容拼接而成;一个双字的内容是该字地址所指向的单元及其后继三个单元的内容拼接而成。在拼接“字内容”时,我们按“高高低低”的原则来处理,即:高存储单元(地址大的存储单元)的值是“字内容”的高8位,低存储单元(地址小的存储单元)的值是“字内容”的低8位。在拼接“双字内容”时也是如此。右图2.8是一段内存单元存放数据的例子。从
39、图中可看出下列存储结果:字节12340H、12341H的内容分别为:12H和34H等;字12340H、12341H的内容分别为:3412H和5634H等;双字12340H、12341H的内容分别为:78563412H和90785634H等。 图2.8一段内存单元存放数据2.2.2 32位微机存储器的管理模式32位微机的内存存管理仍然采用“分段”的管理模式,存储器的逻辑地址同样由段地址和偏移量两部分组成。32位微机的内存管理与16位微机的有相同之处,也有不同之处,因为它提供了两种不同工作方式:实方式和保护方式。1、物理地址的计算方式实方式:段地址仍然是16的倍数,每个段的最大容量仍为64K。段寄
40、存器的值是段的起始地址,存储单元的物理地址仍为段寄存器的值乘16,再加上段内偏移量。在此方式下,32位微机的内存管理与16位微机是相一致的。保护方式:段地址可以长达32位,其值可以不是16的倍数,每个段的最大容量可达4G。段寄存器的值是表示段地址的“选择器”(Selector),用该“选择器”可从内存中得到一个32位的段地址,存储单元的物理地址就是该段地址加上段内偏移量,这与16位微机的物理地址计算完全不同。2、段寄存器的引用32位CPU内有6个段寄存器,程序在某一时刻可访问6个不同的段。其段寄存器的值在不同的方式下具有不同的含义:(1)、在实方式下,段寄存器的值就是段地址;(2)、在保护方式
41、下,段寄存器的值不是段地址,是段地址的“选择器”。它间接指出一个32位的段地址。下面分别说明各段寄存器的用法和作用。代码段寄存器:32位微机在取指令时,系统自动引用CS和EIP来取出下条指令。在实方式下,由于段的最大容量不超过64K,所以,EIP的高16位全为0,其效果相当于16位CPU中的IP。堆栈段寄存器:32位微机在访问堆栈段时,总是引用堆栈段寄存器SS。但在不同的方式下其堆栈指针有所不同:1)、在实方式下,32位微机把ESP的低16位SP作为指向堆栈的指针,所以,我们可以认为栈顶单元是由SS和SP来指定的。这就与16位微机访问栈顶单元的方法相一致;2)、在保护方式下,堆栈指针可用32位
42、的ESP和16位的SP。数据段寄存器:DS是主要的数据段寄存器。通常情况下,它是除访问堆栈以外数据时的默认段寄存器。在某些串操作中,其目的操作数的段寄存器被指定为ES是另一个例外。另外,段寄存器CS、SS、ES、FS和GS也都可以作为访问数据时的段寄存器,但它们必须用段超越前缀的方式在指令中直接写出。用这种方式会增加指令的长度,指令的执行时间也有所延长。一般来说,程序频繁访问的数据段用DS来指向,不太经常访问的数据段可用ES、FS和GS等来指向。3、存储单元的内容32位微机存储单元内容的存储格式与16位微机的完全一致,也都采用“高高低低”的原则来存放数据。2.3 习题2.1、在16位CPU中,
43、有哪些8位寄存器、16位寄存器?哪些16位寄存器可分为二个8位寄存器来使用?2.2、和16位CPU相比,在32位CPU中,扩展了哪些寄存器?哪些寄存器的位数没变?所增加的寄存器是什么?2.3、简述各通用寄存器的主要功能?2.4、简述各段寄存器所指段的含义。2.5、IPEIP寄存器的用途是什么?它是计算机组成原理中的什么概念在CPU中的具体体现?2.6、在标志寄存器中,用于反映运算结果属性的标志位有哪些?它们每一位所表示的含义是什么?在Debug环境下,用什么符号来表示之?2.7、在标志寄存器中,用于反映CPU状态控制的标志位有哪些?它们每一位所表示的含义是什么?在Debug环境下,用什么符号来
44、表示之?2.8、填空1)、16位/32位CPU在取指令时,分别需要用到的寄存器有 和 、 和 ;2)、访问堆栈段栈顶单元要由 段寄存器和 寄存器组合来寻址,访问堆栈段中的单元要由 段寄存器和 寄存器组合来寻址;3)、用基指针(BP)寻址存储器,则其用到的段寄存器是 ;4)、访问数据段中的单元要由 段寄存器和 寄存器组合来寻址;5)、在16位/32位微机系统中,程序最多能同时使用 数据段和 数据段;2.9、假设用以下寄存器组合来访问存储单元,试求出它们所访问单元的物理地址。1)、DS=1000H和DI=2000H3)、SS=2300H和BP=3200H5)、SS=2900H和SP=3A00H2)、DS=2000H和SI=1002H4)、DS=A000H和BX=1000H2.10、在实方式下,一个20位的物理地址最多可有 个段值和偏移量来表示。 2.11、在默认情况下,哪些寄存器可用于读取堆栈段的数据? 2.12、按组画出下列数值在内存中的存储形式(假设同组分配在连续存储单元中)。 1)、字节值:1、2、1、A、a和0;2)、字值:12H、6502H、-1和0;3)、双字值:-765H、12345678H和0;第3章 操作数的寻址方式操作数是指令或