多模块程序设计与混合编程

上传人:j****9 文档编号:54127542 上传时间:2018-09-08 格式:PPT 页数:218 大小:748KB
返回 下载 相关 举报
多模块程序设计与混合编程_第1页
第1页 / 共218页
多模块程序设计与混合编程_第2页
第2页 / 共218页
多模块程序设计与混合编程_第3页
第3页 / 共218页
多模块程序设计与混合编程_第4页
第4页 / 共218页
多模块程序设计与混合编程_第5页
第5页 / 共218页
点击查看更多>>
资源描述

《多模块程序设计与混合编程》由会员分享,可在线阅读,更多相关《多模块程序设计与混合编程(218页珍藏版)》请在金锄头文库上搜索。

1、第9章 多模块程序设计与混合编程,9.1 多模块程序设计的基本概念 9.2 汇编语言程序的多模块连接 9.3 汇编语言与高级程序的连接 习题9,9.1 多模块程序设计的基本概念,在汇编语言程序设计中,源程序所涉及的标识符(变量、标号、段名和过程名等)都在本程序中定义,它与本程序之外的标识符不发生任何关系,这种程序设计称为单模块程序设计。本章将介绍多模块程序设计方法,也称为模块化程序设计方法。所谓模块,从功能上讲它可以是整个大程序中较为独立的一个部分,从源程序结构形式上讲它是由END结束的一个完整程序。,一个源模块可以单独汇编,形成自己的目标模块。最后,由连接程序将各个目标模块连接成一个可执行程

2、序。采用模块化程序设计有下面一些优点:(1) 一个复杂程序可以分成若干个模块,可由不同人员分头完成;(2) 每个模块的任务明确,便于理解;(3) 单个模块易于编写和调试;(4) 便于程序的维护和修改;(5) 可以直接利用已有的模块。,采用模块化程序设计时,必须合理分割模块,严格定义各模块的输入、输出参数和各模块间的通信方式。在单模块程序设计时,模块内所用到的段、变量及标号等各种标识符都必须在本模块内给予定义,否则汇编时将会给出错误信息。多模块程序设计时,由于各个模块都是整个程序的一个部分,因此,各模块之间不仅会有数据上的传递,而且会出现各模块间的变量、标号等标识符的交叉引用。,如何实现这种交叉

3、引用,如何实现各模块间各段的连接是汇编语言多模块程序设计的重要问题,也是本章要叙述的主要内容。此外,多程序模块的连接不仅适用于汇编语言的程序模块,也适用于汇编语言程序模块与高级语言的程序模块的连接。,9.2 汇编语言程序的多模块连接,9.2.1 多模块之间段的连接1SEGMENT语句提供的连接信息段定义的完整语句为段名 SEGMENT 定位类型 组合类型 类别段名 ENDS,在第4章中已指出,段定义后,段名有段地址、偏移地址、定位类型、组合类型和类别 5个属性,前3个属性在第4章中已作过介绍,本节要介绍后两个属性,它们用来为连接过程提供多模块间段连接的有关信息。,1) 组合类型组合类型告诉汇编

4、程序应为连接程序提供本段与其他段连接的有关信息,如本段与其他段是否组合为同一段,一旦组合后,本段信息与其他段信息的关系如何等等。组合类型有6种不同的类型:NONE、PUBLIC、COMMON、AT表达式、STACK和MEMORY。段定义时,组合类型若被省略,则隐含为NONE类型。,NONE类型表示本段与不同模块中的其他段在逻辑上不发生关系,连接后各模块中的各段都有自己的段地址(也称基地址)。PUBLIC类型表明连接时,应把不同模块中属于该类型的同名同类别的段相继地连成一个段,其中所有的变量或标号都有相同的段地址,连接的顺序与LINK时用户所提供的各模块的顺序一致(本节的最后将给出连接的基本方法

5、)。各模块中属于PUBLIC类型的同名同类别的各段的总长度不能超过64 KB。,STACK类型与PUBLIC类型的处理方法一样,只是组合后的这个段用作堆栈。当段定义中指明了STACK类型后,说明堆栈段已经确定,所以,在可执行文件装入内存后段寄存器SS中已是该段的段地址,堆栈指针SP已指向堆栈栈底。故在一般示例中的这两个寄存器传送初值的指令可以省去。,COMMON类型表明连接时,应将不同模块中属于该类型的同名同类别的各段连接成一段,它们共用一个基地址,且互相覆盖。连接后,段的长度取决于最长的COMMON段的长度。AT表达式类型表明连接时,应将本段装在根据表达式求值得到的16位段地址上,表达式也可

6、以是一个有效的常数。该类型可以将我们要定义的段设定在固定的地址范围内。必须注意,定义AT类型的段内不应包括任何指令语句或有初值的变量定义语句,但该段内允许设定标号,与标号有相同属性的过程定义语句或无初值的变量定义语句,这种类型仅仅用来将该段指向内存区中的某个段,,使该段的段名及段内的变量与指向的内存区的段地址有关。例如,若要用一个过程名SUB1代表BIOS中的某段子程序,我们可以这样定义一个段和过程:CODEB SEGMENT AT表达式1ORG NSUB1 PROC FARSUB1 ENDPCODEB ENDS,其中,表达式1的值即为某子程序所在段的段地址,N即为该子程序在段内的偏移地址。这

7、样定义后,程序中调用过程名SUB1时,即调用BIOS中对应的子程序。其中也可以定义一个标号,并用ORG指定该标号的偏移地址,这样,该标号就与该段内的这个偏移地址相关。,MEMORY类型表明连接时应把本段装在被连接的其他所有段之上(地址高端),当有多个段为此类型时,只有汇编程序遇到的第1个段才认为是MEMORY段,而其他段则当作COMMON类型。图9.1给出了不同模块中组合类型为PUBLIC和COMMON时的连接结果。图中两个模块的数据段都为COMMON类型,连接后,这两个段组合成一个段,并且互相覆盖,其长度取两个模块中段长度长的段,即为第2模块的长度。由于COMMON类型的段组合后,相互覆盖,

8、所以,只有不同模块采用公用缓冲区时才使用这种类型。,图9.1中两个模块的代码段为PUBLIC类型,因此,连接后,两个模块的代码段也组合成一个段,但它们并不覆盖,而且两个代码段相邻地连接在一起,其顺序也与LINK时提供的目标模块的顺序一致。组合后段的长度应是两个代码段长度的和。图9.1中两个源模块中的数据段和代码段都没有给出类别,这也是允许的,但若某个模块中给出了类别而另一模块中不给出类别,那么,这两个模块中的同名段将不能组合成一个段,它们被认为不是同类别的段。模块1和模块2如下:,图9.1 PUBLIC和COMMON的连接结果,模块1: DATA SEGMENT COMMOMDW 20H DU

9、P(?) DATA ENDS CODE SEGMENT PUBLIC CODE ENDS,模块2: DATA SEGMENT COMMOMDW 30H DUP(?) DATA ENDS CODE SEGMENT PUBLIC CODE ENDS,2) 类别类别可以是任何一个合法的名称,但必须用单引号括起来。连接时,将把不同模块中相同类别的各段在物理上相邻地连接在一起,其顺序亦与LINK时提供的各模块顺序一致。当类别相同的各段的段名不同时,它们连接后虽在同一物理段内,但实际上它们仍不属于同一个段,也就是说它们的段基址不相同。这样做的一个好处仅是便于程序的固化。在编程时,它们都是独立的代码段,各段

10、有各自的段基地址,但连接后,它们却在同一物理段,从而可以把各段程序固化在一起。,2. GROUP伪指令GROUP伪指令格式为段组名 GROUP 段名 , 段名, 格式中的段组名是用户自己定义的一个标识符,其定义规则和语句名的定义规则相同,格式中的段名是本模块中已定义的段的名称。,GROUP伪指令提供了段的另一种组合形式。它把多个由SEGMENT语句定义的段组合在同一段组中,用一个段组名表示。同一段组内的各段将装在同一物理段内,它们有相同的段基址。同一段组内,段的数目不受限制,但总字节数不能超过64 KB,同一段组内的各段的组合类型和类别可以不同。,【例9-1】 GROUP伪指令应用举例。 模块

11、1: AGROUPGROUP CODE1,CODE2 ;定义了一个段组AGROUP CODE1 SEGMENT ASSUME CS: AGROUP START: CODE1 ENDS CODE2 SEGMENT ASSUME CS: AGROUP,CODE2 ENDS END START 模块2: AGROUP GROUP CODE3 CODE3 SEGMENT ASSUME CS: AGROUP CODE3 ENDS END,例中有2个模块3个段,连接后这3个代码段都将组合在同一物理段内,各模块中的CS都指向该段组名(AGROUP所代表的段地址),3个代码段中的所有标号或变量都有相同的段基地

12、址。从上面的介绍我们看到,段定义中的组合类型、类别和段组定义都为多模块之间段的连接提供了必要的信息,但它们又不完全相同。组合类型中的PUBLIC、STACK和COMMON类型都指出将把各模块中的相应段组合成一个段,且有相同的段基址,但前提是这些段的段名和类别必须相同。,段组定义同样也指出将把各模块中的相应段组合成一个段,且有相同的段基址,但它对各段的段名和段的类型没有限制,并且各段还可以有自己的段基址,这对于将分头编写的多个模块组合成一个段提供了方便,也就是说只要在各模块中加一条段组名相同的段组定义语句即可。,类别则指出了各模块中凡是类别相同的各段不论其段名和组合类型如何,都将它们组合在同一物

13、理段内,但它们的段地址却不一定是相同的,只有当段名相同且组合类型为PUBLIC、STACK和COMMON之一时,段地址才相同。类别的这一功能对程序的固化带来了方便,我们可以把编程时并不属于同一段的程序或数据组合在一起(同一物理段内)。,此外,组合类型还为连接程序提供了当这些段组合成一段后,段内信息关系的有关信息。如PUBLIC和STACK类型是将各模块中的所有信息都顺序地连接在一起,互不覆盖,而COMMON类型组合后各模块中的信息互相覆盖,这对当各模块需要一个公共缓冲区时是十分有用的。,9.2.2 模块间的交叉访问模块间的交叉访问是指一个模块中要引用另一个模块中定义的变量、标号等标识符。例如,

14、主模块中要调用的过程名是在另一个子模块中定义的,子模块中要用到的变量可能是在主模块中定义的。这样,一个源模块中定义的标识符就可能有两类:一类是供本模块使用的,我们称它们为局部标识符;另一类是同时可供本模块和其他模块使用的,我们称这类标识符为外部标识符或全局标识符。,那么,如何告诉汇编程序本模块中哪些标识符是全局的(也就是可以被其他模块引用的),哪些标识符是要引用外部的(也就是本模块中没有定义的),以及出现了交叉访问后,汇编语言程序编程又应注意些什么问题,这些都是本节所要讨论的主要内容。,1. 伪指令PUBLIC和EXTRN1) 伪指令PUBLIC伪指令PUBLIC的功能是指明本模块中所定义的标

15、识符有哪些是可以提供其他模块调用的外部标识符。格式如下:PUBLIC 标识符,标识符,其中,PUBLIC是伪指令操作码助记符,其后的标识符就是本模块内定义的可供其他模块调用的标识符,它可以是变量名,也可以是标号或过程名。,2) 伪指令EXTRN伪指令EXTRN的功能是指出本模块中用到的哪些标识符是由其他模块定义的。格式如下:EXTRN 标识符:类型,标识符:类型,其中,EXTRN是伪指令操作码助记符,其后的标识符就是本模块中要引用的外部标识符。这里,标识符必须指出其类型,这是在汇编时为了生成正确的机器码所必需的。变量的类型可以是BYTE、WORD或DWORD,标号的类型可以是NEAR或FAR。

16、,各模块中语句由PUBLIC和EXTRN提供的标识符必须互相呼应。连接时,连接程序将检查各模块中EXTRN语句中的每个标识符是否与PUBLIC语句中的标识符相配合。若EXTRN语句中出现的标识符在PUBLIC语句中找不到,说明该标识符未定义,连接程序将给出错误信息,如例9-2所示。例9-2各模块中要引用的外部变量有VAR1、VAR2、VAR3和VAR4,但在PUBLIC语句中说明可以提供给其他模块引用的外部变量为VAR1、VAR2、VAR3和VAR5,说明变量VAR4没有定义,从而出错;而变量VAR5是由模块3定义的外部变量,,例中没有被其他模块引用,这是允许的。此外,模块1与模块2的代码段连接后是一个段,所以,在模块1中要用到的标号EX1虽不在同一模块中,但却是NEAR类型。标号EX2在模块3中定义,连接后它与模块1的代码段不在同一段,因而EX2为FAR类型。,【例9-2】 模块间交叉定义示例一。语句PUBLIC和EXTRN提供的标识符必须互相呼应。模块1:EXTRN VAR3:WORD,EX1:NEAREXTRN EX2:FARPUBLIC VAR1,VAR2DATA SEGMENTVAR1 DB ?VAR2 DW ?,

展开阅读全文
相关资源
正为您匹配相似的精品文档
相关搜索

最新文档


当前位置:首页 > 生活休闲 > 科普知识

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号