模块化程序设计 .ppt
《模块化程序设计 .ppt》由会员分享,可在线阅读,更多相关《模块化程序设计 .ppt(64页珍藏版)》请在三一办公上搜索。
1、第14章 模块化程序设计,14.1 段间调用 14.2 定义外部标识符伪指令 14.3 使用EXTRN和PUBLIC的范例 14.4 在指令段使用PUBLIC 14.5 在数据段使用PUBLIC 14.6 参数传送 14.7 C语言与汇编语言的链接,14.1 段 间 调 用,前面介绍的CALL 指令都是段内的调用,即在同一个指令段内。段内调用的CALL指令范围为0000HFFFFH。一条段内调用指令(CALL)的目的码是3个字节长度,例如:E8 2000(0020);十六进制,十六进制E8是段内调用指令(CALL)机器指令的操作码,其操作是先把当前IP指令指针寄存器的值压入堆栈保存,这个值是C
2、ALL的下一条指令地址;然后,再把被调用的子程序的偏移地址(2000逆序)值送入IP 寄存器,IP0020。微处理器把当前CS的值和IP的值相结合形成物理地址,此地址指向被调用子程序的第1字节。当子程序的执行中,遇到RET指令离开子程序返回时,RET指令会从堆栈中弹出IP的保留值,并把它装入IP,使程序返回到CALL的下一条指令继续执行,这个过程是段内调用。,其特点是在子程序调用、返回过程中段寄存器CS不变化,只有指令指针寄存器IP发生变化。主程序与被调用的子程序同在一个段内。模块化程序设计必然涉及到模块间的调用问题。模块间的调用是通过段间的调用来实现的。若被调用的子程序是在现指令段之外,则称
3、为段间调用。一条段间调用指令(CALL)的机器指令码共有5个字节。例如:9A 0002 AF04(04AF 0200);十六进制,十六进制9A是段间调用指令(CALL)机器指令的操作码。操作是:首先将CS段寄存器的值压入堆栈,并把被调用子程序所在段的段值(AF04逆序)装入CS段寄存器,CS04AF;然后把IP指令指针寄存器的值压入堆栈,并将被调用子程序相应的偏移地址(0002逆序)装入IP,IP0200。,这些操作建立了被调用子程序的第一条待执行指令的地址:十六进制 段 值:CS 04AF0 偏移地址:IP+0200 物理地址:04CF0,当离开子程序返回时,段间调用的RET指令会从堆栈中依
4、序弹出IP和CS两个寄存器的原值,返回到CALL的下一条指令。其特点是在子程序调用、返回过程中,段寄存器CS和指令指针寄存器IP均发生变化。主程序与被调用的子程序不在同一个段内。,14.2 定义外部标识符伪指令,当进行模块化程序设计时,首先应考虑的问题是模块间控制的耦合和数据的耦合。控制耦合就是模块在怎样的环境下如何进入又如何退出。数据耦合就是诸模块间如何进行数据通讯。例如,有一个主模块(MAINPROG)调用一个子模块(SUBPROG),它要用到一个段间调用(CALL),如图14-1所示。,图14-1 段间调用,主模块MAINPROG内的CALL指令,必须知道子模块SUBPROG是位于本段之
5、外的标号。否则汇编过程中会产生一个错误信息指出SUBPROG是一个未定义的符号。EXTRN伪指令就是执行此功能的,它告诉汇编程序SUBPROG是一个远程的标号(FAR Label),是定义在另一个模块里的。因为汇编程序无法知道真是如此,所以就产生“空的”目的操作数0000,即先空出;而由链接程序在链接时再填入确定值。例如(参考例14.4主模块程序清单):0011 9A0000-E,子模块SUBPROG内含有一个PUBLIC伪指令,它告诉汇编程序和链接程序,其他模块需要知道SUBPROG的地址。当MAINPROG与SUBPROG都已汇编成目的模块文件后,它们可以下列的方式来链接:LINK MAI
6、NPROG+SUBPROG Run File MAINPROG.EXE:List File NUL.MAP:CON Libraries.LIB:,链接程序将一个目的模块内的EXTRN匹配上另一个模块内的PUBLIC,并将插入所有需要的偏移地址,然后把两个目的模块组合成一个可执行的文件。若有不匹配的情况,链接程序会给出错误信息。利用EXTRN和PUBLIC这两条伪指令,一个模块可以访问其他模块的标识符(变量或者标号)。如果一个标识符只在这一个模块中定义过,那么它相对这个模块就是一个内部的标识符或局部标识符。如果它没有在这一个模块中定义过,而是在其他一个模块中定义过,那么它相对于该模块就称为外部标
7、识符。,对于只产生一个单一目标模块的汇编语言程序而言,它所访问的所有标识符必须是局部(内部)定义的,否则就会产生一个错误信息汇编程序会查出有一个未定义的标识符(标号或变量)存在。对于多模块程序来说,必须给汇编程序一个信息以说明其间的有些标识符是外部的,而不至于汇编程序把它们理解为一些无效的标识符。此外为了允许其他模块访问本给定模块中的标识符,该给定模块必须包含一个标识符清单,以说明其中的标识符可以让其他模块访问。因此,每个模块可含有(不一定绝对含有)两个清单,一个清单表明它所访问其他模块的外部标识符(EXTRN),而另一个则列出它所定义的且让其他模块访问的标识符(PUBLIC);,这两个清单靠
8、EXTRN和PUBLIC这两条伪指令来列出。EXTRN和PUBLIC伪指令的格式如下:EXTRN 标识符:类型,PUBLIC 标识符,EXTRN伪指令里的标识符是被申明的外部的变量或标号,而PUBLIC伪指令里的标识符是供其他模块使用的变量或标号。由于在产生相应的机器代码之前,汇编语言必须要知道所有标识符的类型,以便确定指令的字节数(长度),故在EXTRN伪指令里的每一个标识符都伴有类型符出现。,对于变量来说,类型有BYTE、WORD、DWORD等,对于标号来说类型则有NEAR或FAR。注意:标识符可以是变量、符号常量、标号和过程名。例如:INC VAR1 语句,如果VAR1是外部变量,并且是
9、一字变量,那么在含有这个语句的模块中必须使用下列伪指令:EXTRN,VAR1:WORD 而在定义VAR1的模块中则一定要有下面的伪指令:PUBLIC,VAR1,链接程序的主要任务之一,就是检测并证实EXTRN语句里的每一个标识符是否与PUBLIC语句的标识符相匹配,如果不相匹配,链接程序就会给出出错信息。下面给出三个模块,说明链接程序是怎样查找匹配,并指出其中错误。,模块1:EXTRN VAR2:WORD,LAB2:FARPUBLIC VAR1,LAB1;DATA1 SEGMENT VAR1 DB 2 VAR3 DB?VAR4 DW?DATA1 ENDS;,LAB1:模块2:EXTRN VAR
10、1:BYTE,VAR4:WORDPUBLIC VAR2 链接错误,原因是模块1中PUBLIC;没有申明匹配 DATA2 SEGMENT VAR2 DW 0 VAR3 DB 5 DUP(?)DATA2 ENDS;,模块3:EXTRN LAB1:FARPUBLIC LAB2,LAB3;其他模块未使用LAB2:不需申明LAB3:,14.3 使用EXTRN和PUBLIC的范例,下面的例子中含有两个模块:主模块CALLMUL1和一个子模块SUBMUL1。主模块定义了堆栈段、数据段和指令段。数据段定义了两个数据项PRICE和QTY。指令段分别把PRICE和QTY装入AX和BX寄存器,然后调用子模块。主模块
11、内的伪指令EXTRN指明了本模块使用的外部模块SUBMUL1。,子模块内有一条伪指令PUBLIC,它告诉链接程序SUMUL1是由其他模块调用的,同时指明此处是链接的进入点。子模块的功能是把AX寄存器的内容乘以BX寄存器的内容,所得乘积放入DX:AX这一对寄存器内。子模块内没有定义任何数据,所以它没有数据段;也可以定义数据段,但只能在子模块中使用。在子模块内也没有定义堆栈段,它与主模块共同使用一个堆栈。所以,在主模块中定义的堆栈,子模块也可以使用。链接程序要求至少有一个堆栈段,在主模块内定义的堆栈段就可以满足要求。,例14.1 EXTRN和PUBLIC应用。主模块程序清单如下:;主模块:;fil
12、ename:CALLMUL1.ASMEXTRN SUBMUL1:FAR;STACK SEGMENT PARA STACK STACK DW 64 DUP(?)STACK ENDS,;DATASGSEGMENT PARA DATAQTY DW 0140HPRICE DW 2500HDATASGENDS;CODESG SEGMENT PARA CODEBEGIN PROC FAR ASSUME CS:CODESG,DS:DATASG,SS:STACK,PUSH DS SUB AX,AX PUSH AX MOVAX,DATASG MOV DS,AX MOV AX,PRICE MOV BX,QTY C
13、ALL SUBMUL1 RETBEGIN ENDPCODESG ENDS END BEGIN,子模块程序清单如下:;filename:SUBMUL1.ASM;子模块:CODESG SEGMENT PARA CODESUBMUL1 PROC FAR ASSUME CS:CODESG PUBLIC SUBMUL1 MUL BX RET,SUBMUL1 ENDPCODESG ENDS END SUBMUL1主模块和子模块分别汇编正确无误后,参考上节内容链接,产生一个EXE文件。C:masmLINK CALLMUL1+SUBMUL1Run File CALLMUL1.EXE:Enter(回车)List
14、 File NUL.MAP:EnterLibraries.LIB:Enter,14.4 在指令段使用PUBLIC,在主模块的指令段和子模块的指令段使用PUBLIC伪指令,链接程序会把两个逻辑指令区段结合成一个实际的指令段。在例14.1的主模块和子模块中各有一处修改,均是在指令段的SEGMENT伪指令内使用PUBLIC,用法如下:COD ESG SEGMENT PARA PUBLIC CODE,例14.2 在指令段使用PUBLIC。主模块程序清单如下:;主模块:;filename:CALLMUL.ASMEXTRN SUBMUL:FAR;STACK SEGMENT PARA STACK STACK
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- 模块化程序设计 模块化 程序设计
链接地址:https://www.31ppt.com/p-5361051.html