例4.1
; * * * * * * * * * * * * * * * * * * * * * * *
data_seg1 segment ; 定义数据段
.
.
.
data_seg1 ends
; * * * * * * * * * * * * * * * * * * * * * * *
data_seg2 segment ; 定义附加段
.
.
.
data_seg2 ends
; * * * * * * * * * * * * * * * * * * * * * * *
code_seg segment ; 定义代码段
assume cs:code_seg, ds:data_seg1, es:data_seg2
start: ; 程序执行的起始地址
; set DS register to current data segment
mov ax, data_seg1 ; 数据段地址
mov ds, ax ; 存入DS寄存器
; set ES register to current extra segment
mov ax, data_seg2 ; 附加段地址
mov es, ax ; 存入ES寄存器
.
.
.
code_seg ends ; 代码段结束
; * * * * * * * * * * * * * * * * * * * * * * * * * *
end start
由于ASSUME伪指令只是指定某个段分配给哪一个段寄存器,它并不能把段地址装入段寄存器中,所以在代码段中,还必须把段地址装入相应的段寄存器中:
MOV AX,DATA_SEG1 ; 数据段地址
MOV DS,AX ; 存入DS寄存器
MOV AX,DATA_SEG2 ; 附加段地址
MOV ES,AX ; 存入ES寄存器
如果程序中还定义了堆栈段STACK_SEG,也需要把段地址装入SS中:
MOV AX,STACK_SEG ; 堆栈段地址
MOV SS,AX ; 存入ES寄存器
注意,在程序中不需要用指令装入代码段的段地址,因为在程序初始化时,装入程序已将代码段的段地址装入CS寄存器了。
为了对段定义作进一步地控制,SEGMENT伪指令还可以增加类型及属性的说明,其格式如下:
段名 SEGMENT [定位类型][组合类型]['类别']
.
.
.
段名 ENDS
[ ]中的内容是可选的,一般情况下,这些说明可以不用。但是,如果需要用连接程序把本程序与其他程序模块相连接时,就需要提供类型和属性的说明。
表4.2.1 ·定位类型:说明段的起始边界值(物理地址)。
定位类型
|
说 明
|
BYTE
|
段可以从任何地址边界开始
|
WORD
|
段从字边界开始,即段的起始边界值为偶数
|
DWORD
|
段从双字的边界开始,即段的起始边界值为4的倍数
|
PARA
|
段从小段边界开始,即段的起始边界值为16 (或10H) 的倍数
|
PAGE
|
段从页边界开始,即段的起始边界值为256 (或100H) 的倍数
|
注意:
定位类型的缺省项是PARA,即在未指定定位类型的情况下,则连接程序默认为PARA。BYTE和WORD用于把其它段(通常是数据段)连入一个段时使用;DWORD一般用于运行在80386及后继机型上的程序。
表4.2.2 ·组合类型:说明程序连接时的段组合方法。
组合类型
|
说 明
|
PRIVATE
|
该段为私有段,连接时将不与其它模块中的同名段合并
|
PUBLIC
|
该段连接时将与其它同名段连接在一起,连接次序由连接命令指定
|
COMMON
|
该段在连接时与其它同名段有相同的起始地址,所以会产生覆盖
|
AT 表达式
|
段地址=表达式的值,其值必为16位但AT不能用来指定代码段
|
MEMORY
|
与PUBLIC同义
|
STACK
|
将多个同名堆栈段连接在一起,SP设置在第一个堆栈段的开始
|
注意:组合类型的缺省项是PRIVATE。
例4.2
在连接之前已定义两个目标模块如下:
模块1 SSEG SEGMENT PARA STACK
DSEG1 SEGMENT PARA PUBLIC 'Data'
DSEG2 SEGMENT PARA
CSEG SEGMENT PARA 'Code'
模块2 DSEG1 SEGMENT PARA PUBLIC 'Data'
DSEG2 SEGMENT PARA
CSEG SEGMENT PARA 'Code'
以上两个模块分别汇编后产生 .OBJ 文件,经连接程序连接后产生的 .EXE模块如下:
模块1 CSEG SEGMENT PARA 'Code'
模块2 CSEG SEGMENT PARA 'Code'
模块1+2 DSEG1 SEGMENT PARA PUBLIC 'Data'
模块1 DSEG2 SEGMENT PARA
模块2 DSEG2 SEGMENT PARA
模块1 SSEG SEGMENT PARA STACK