汇编学习笔记49

第八章 模块化程序设计

本章要点:

1. 掌握段的完整定义及简化定义

2. 知道模块间的通信及子程序库

一、段的完整定义

(一) 完整的段定义

段名 SEGMENT [定位类型] [组合类型] [类别]

……

语句

……

段名 ENDS

通知汇编程序和连接程序如何建立和组合段

1. 段名

段名可以是唯一的,也可以与程序中其他的段名相同。在同一个模块中,如果已用相同的段名定义过段,那么当前这个段就被视为前一个同名段的继续,即同一个段。

对一个模块中的同名段而言, 后续同名段的定义伪指令SEGMENT中的可选项取值应该与前一个同名段相同,或者不再指定可选项的值而默认与前一个同名段相同

2. 定位类型

定位类型表示出当前段对起始地址的要求,从而指示连接程序如何衔接相连两段。

一般情况下,缺省的定位类型是PARA,即段起始地址于可用的第一个节(每节16个字节)的边界处

定位类型BYTE使得当前段紧接前一段,前后两段之间没有空间单元,所以是最节约的定位类型。

定位类型WORD使得段从偶地址开始,不仅较为节约,而且有利于数据单元定位在偶地址。

定位类型DWORD常用于8086的32位段。

一页等于256字节,所以定位类型PAGE可能导致最大的段间隔。

例1: 下程序的两个段定位类型均为PARA

DSEG SEGMENT PARA COMMON

MESS DB 'HELLO!', 0DH, 0AH, '$'

DSEG ENDS

CSEG SEGMENT PARA PUBLIC

ASSUME CS: CSEG, DS: DSEG

START: MOV AX, DSEG

MOV DS, AX

MOV DS, OFFSET MESS

MOV AH, 9

INT 21H

MOV AX, 4C00H

INT 21H

CSEG ENDS

END START

3. 组合类型

组合类型就是用于通知连接程序,如何把不同模块间段名相同的段组合在一起。

有如下组合类型:

(1) PUBLIC

  表示当前段与其它模块中的组合类型为PUBLIC的同名段组合成一个段,组合的先后顺序取决于启动LINK程序时目标模块名排列的次序

(2) COMMON

  表示当前段与其它模块中的同名段重叠,即起始地址相同,最终段的长度等于它们中最长的段的长度。

(3) STACK

  组合类型STACK表示当前段是堆栈段,组合情况与PUBLIC相同

(4) MEMORY

  组合类型MEMORY与PUBLIC相同

(5) AT表达式

  表示当前段应该绝对地址定位,其地址即为表达式之值。LINK程序不对AT段生成任何代码或数据。

(6) PRIVATE

  组合类型PRIVATE表示不与其它段组合,宏汇编程序MASM不识别此关键字。

若段定义伪指令SEGMENT语句中没有给出组合类型,就表示不与其它段组合。

例2:

某程序第一个源程序模块为例1, 第二个源程序模块如下所示:

DSEG SEGMENT PARA COMMON

DB 'OK'

DSEG ENDS

CSEG SEGMENT PARA PUBLIC

MOV AH, 4CH

INT 21H

CSEG ENDS

先把这两个源程序模块分别汇编,最后用LINK程序连接,命令如下:

LINK 例1 + 例2

模块2中的DSEG段与模块1中的DSEG段重叠, 模块2中的CSEG段和模块1中的CSEG段合并成一个段。

最后得到了可执行程序的内容如下:

0000: 0000        ; 两个段重叠后的结果为 'OKLLO..$'

0000: 0008        ; CSEG的类型类型是PARA导致的间隔

0001: 0000        ; MOV AX, 26H, 模块1中的CSEG段

4. 类别

类型用于表示段的分类。LINK程序总是使类型相同的段相邻,实际上只有类型相同的同名段才根据组合类型进行组合。

类别是一个由程序员指定的字符串,但必须使用单引号括起来。如果一个段没有给出类型,那么这个段的类别就为空。

例3:

设某个程序的模块甲如下:

; 模块甲(MODULE1)

DSEG SEGMENT PARA PUBLIC 'DATA'

DSEG ENDS

CSEG SEGMENT PARA PUBLIC 'CODE'

START:…

CSEG ENDS

END START

模块乙如下:

; 模块乙(MODULE2)

DSEG SEGMENT PARA PUBLIC 'XYZ'

DSEG ENDS

ASEG SEGMENT PARA PUBLIC 'CODE'

START: …

ASEG ENDS

END START

模块丙如下:

; 模块丙(MODULE3)

ESEG SEGMENT PARA PUBLIC 'DATA'

START: …

ESEG ENDS

END START

用以下命令把它们连接起来:

LINK MODULE1+MODULE2+MODULE3

在程序中各段的排列顺序如下:

模块甲的DSEG, 模块丙的ESEG, 模块甲的CSEG, 模块乙的ASEG, 模块乙的DSEG

(二) 完整的段定义(堆栈段说明)

一个完整的汇编程序一般应含有一个堆栈段,只有COM程序例外。

在程序的其它模块中也有组合类型为STACK的同名段,那么连接时将以连接的方式组合在一起,这样会构成一个存储空间更大的堆栈。

例4: 增加一个大小为1024字节的堆栈段

SSEG SEGMENT PARA STACK

DB 1024DUP(?)

SSEG ENDS

DSEG SEGMENT PARA COMMON

MESS DB 'HELLO', 0DB, 0AH, $

DSEG ENDS

CSEG SEGMENT PARA PUBLIC

CSEG ENDS

END START

LINK 程序会把组合类型为STACK的段的有关信息写入可执行文件中,设置的SS值是组合类型为STACK的段的段值。设置SP值是堆栈段的大小。

(三) 段组的说明和使用

例5: 下面的程序含有两个数据段和一个代码段

DSEG1 SEGMENT PUBLIC

VAR1 DB ?

DSEG1 ENDS

DSEG2 SEGMENT PUBLIC

VAR2 DB ?

DSEG2 ENDS

CSEG SEGMENT PARA PUBLIC

ASSUME CS: CSEG, DS: DSEG1

START: MOV AX, DSEG1

MOV DS, AX

MOV BL, VAR1

……

ASSUME DS: DSEG2

MOV AX, DSEG2

MOV DS, AX

MOV VAR2, BL

MOV AH, 4CH

INT 21H

CSEG ENDS

END START

 

另一种写法:

DSIS GROUP DSEG1, DSEG2

DSEG1 SEGMENT PUBLIC

VAR1 DB ?

DSEG1 ENDS

 

DSEG2 SEGMENT PUBLIC

VAR2 DB ?

DSEG2 ENDS

CSEG SEGMENT PARA PUBLIC

ASSUME CS: CSEG, DS: DSIS

START: MOV AX, DSIS

MOV DS, AX

MOV BL, VAR1

……

MOV VAR2, BL

MOV AH, 4CH

INT 21H

CSEG ENDS

END START

posted @ 2011-01-26 20:53  杨海龙  阅读(962)  评论(0编辑  收藏  举报