首页 | 新闻 | 新品 | 文库 | 方案 | 视频 | 下载 | 商城 | 开发板 | 数据中心 | 座谈新版 | 培训 | 工具 | 博客 | 论坛 | 百科 | GEC | 活动 | 主题月 | 电子展
返回列表 回复 发帖

目标代码文件的连接和子程序库的调入

目标代码文件的连接和子程序库的调入

用INCLUDE伪指令包含其它文件,其实质仍然是一个源程序,只是分成几个文件书写;被包含的文件不能独立汇编,使依附主程序而存在的。所以合并的源程序之间的各种标识符,应该统一规定,不能发生冲突,另外由于是源程序的结合,每次汇编都要包括对被包含文件文本的汇编,增加了汇编的时间。
汇编程序还提供了目标代码级的结合方法,可以把常用子程序写成一个或几个相对独立的源程序文件,单独汇编他们,形成若干个常用子程序的目标文件.OBJ。主程序也经过独立里汇编之后形成目标文件,利用连接程序将多个目标文件连接起来,最终产生可执行文件。常见独立的文件称为模块,所以这种方法也称为模块的连接。利用目标文件的连接开发源程序,需要注意几个问题:
1、首先各个模块间共用的变量、过程等要用PUBLIC/EXTERN伪指令说明
整个程序开发过程中,一个文件可能要利用另一个文件定义的变量或过程。由于各个源程序文件独立汇编,所以MASM提供PUBLIC伪指令用于说明眸个变量或过程等可以被别的模块使用;同时提供EXTERN(MASM5。x是EXTRN)伪指令用于说明某个变量或过程式在别的模块中定义。他们的格式为:
PUBLIC 标识符 [,标识符...]               ;定义标识符的模块使用
EXTERN 标识符:类型 [,标识符:类型...]   ;调用标识符的模块使用
其中标识符是变量名、过程名等;类型是byte/word/dword(变量)或near/far(过程)。在一个源程序中,PUBLIC/EXTERN语句可以有多条。各模块间的public/extern伪指令要相互配对,并且指明的类型相互一致。
2、要设置好段属性,进行正确的段组合
由于各个文件独立汇编,所以子程序文件也必须定义在代码段中,也可以具有局部的数据变量。采用简化段定义格式,因为缺省段名(如_TEXT)、类别(如'code')相同,组合类型都是public,所以只要采用相同的存储模式,容易实现正确的近或远调用。完整段定义中,为了实现模块间的段内近调用(near类型),各自定义的段名、类别必须相同,组合类型都是public;因为这是多个段能够组合成一个物理段的条件。实际的程序开发中,各个模块由不同的程序员完成,不易实现段名或类别相同,所以索性定义成远调用(far类型)。此时,extern语句中要与之配合、声明正确。定义数据段时,同样要注意这个问题。当各个模块的数据段不同时,要正确设置数据段的DS
3、要处理好各个模块间的参数传递问题。
子程序间的参数传递方法,同样是模块间传递参数的基本方法。少量参数可以使用寄存器或堆栈直接传送数据本身;大量数据可以安排在缓冲区,然后用寄存器或堆栈传送数据的存储地址;还可以利用变量传递参数,但是要采用public/extern声明为公共(全局)变量;采用段覆盖传递参数时,数据段的段名、类别要相同,组合类型是common
4、各个模块独立汇编,用连接程序将各个模块结合起来
需要连接起来形成一个可执行文件的若干个模块中,必须有一个且只能有一个模块中含有主程序,其他模块为子程序。
例31.1:利用目标文件连接方法实现将输入的数据安升序输出。
分析:为了简化问题,将宏定义并入主程序。3个子程序还是一个文件,为了演示参数传递,将input子程序的出口参数改为利用变量count,并定义成远调用。
      ...                                        ;宏定义
      .code
      public count                               ;定义count共用
      extern aldisp:near,sorting:near,input:far  ;其他模块的子程序
      .startup
      ...
      .exit 0                                    ;去掉30-1.asm中的包含语句
      end
现在的子程序文件sub31-1.asm,要加上段定义语句、声明语句等,不需要主程序那样的起始点和结束点,作少量修改:
      .model small
      extern count:word
      .code
      public aldisp,sorting,input
aldisp   proc
       ...
sorting  proc
       ...
input    proc far
       ...
       mov count,cx           ;提供出口参数
       pop dx
       pop ax
       ret
input  endp
       end
上述两个源文件分别汇编,各自产生目标文件31-1.obj和sub31-1.obj,然后利用连接程序进行连接:
link 31-1.obj + sub31-1.obj
实际上,进行连接的目标文件可以用汇编程序产生,也可以用其他编译程序产生。所以,利用这种方法还可以实现汇编语言程序模块和高级语言程序模块的连接,实现汇编语言和高级语言的混合编程。
子程序库的调入
较之源程序包含方法,目标文件的连接进一步提高了开发程序的效率,但是由于被连接的每个目标文件的全部代码都会成为最终可执行文件的一部分,未使用的子程序也将出现在可执行程序中,使可执行程序庞大。MASM汇编程序提供了子程序库方法克服这个缺点。子程序库文件(.LIB)是子程序模块的集合,其中存放着各种子程序的名称、目标代码以及定位信息。
存入库的子程序的编写与目标文件连接方法中的要求一样,只是为方便调用,更加严格。例如各个子程序的参数传递方法要一致;子程序类型最好一样(都为NEAR或FAR),都采用相同的存储模式;采用一致的寄存器保护措施和可能需要的堆栈平衡措施等。
子程序文件编写完后,汇编形成目标文件,然后利用库管理工具程序LIB.EXE,把子程序目标模块逐一加入到库中。格式如下:
LIB 库文件名 + 子程序目标文件名
例31.2:利用子程序库调用方法实现将输入的数据按色升序输出
分析:把3个子程序分成3个文件,形成3个模块,组合到子程序库sub31-2.lib中,各个子程序均采用寄存器传递参数,都是近调用。
子程序aldisp形成文件要加上段定义语句、声明等:
.model small
.code
public aldisp
aldisp proc
       ....
aldisp  endp
     end
子程序sorting形成的文件也要加上段定义语句、声明语句。子程序input除了加上段定义语句、声名语句外,还要修改为近调用,删除“mov count,cx”语句
最后汇编主程序和3个子程序,形成目标文件:主程序31-2.obj,子程序aldisp.obj、sorting.obj和input.obj文件。利用子程序库管理程序LIB.EXE,把3个子程序组合到子程序库32-2.lib,如下:
lib 32-2.lib + aldisp.obj + sorting.obj + input.obj
最后用连接程序形成可执行文件:
link 32-2.obj
Run File[32-2.exe]:
List File[nul.map]:
Libraries[.lib]:32-2.lib
Definitions File[nul.def]
继承事业,薪火相传
返回列表