汇编语言程序设计(五)

原创 2010年10月08日 15:52:00

4 段的基本属性

在通常情况下一个复杂的应用程序会由若干个模块组成一个模块又会含有多个段。而不同模块的段之间、同一模块的段之间往往存在某种联系,这种联系就要体现在段属性的说明上。

 

段定义的一般格式如下:

 

段名 SEGMENT [对齐类型] [组合类型] [类别]

段名 ENDS

 

段属性“对齐类型”、“组合类型”和“类别”要按此顺序说明,但这些可选项可根据需要选择书写。如果源程序中不指定某个属性,那么,汇编程序将使用该属性的缺省值。

 

程序中的段名可以是唯一的,也可以与其它段同名。在同一模块中,如果有二个段同名,则后者被认为是前段的后续,这样,它们就属同一段。

 

当同一模块出现二个同名段时,则后者的可选项属性要么与前者相同,要么不写其属性而选用前者的段属性。

 

例,同段名的作用:

DATA1 SEGMENT        ;第一个数据段

MSG DB "Hello, "

DATA1 ENDS

CODE1 SEGMENT        ;第一个代码段

ASSUME CS:CODE1, DS:DATA1

START: MOV AX, DATA1

MOV DS, AX

MOV DX, offset MSG

MOV AH, 9

INT 21H

CODE1 ENDS

DATA1 SEGMENT        ;第二个数据段

DB "World.$"

DATA1 ENDS

CODE1 SEGMENT        ;第二个代码段

MOV AX, 4C00H

INT 21H

CODE1 ENDS

END START

END

 

在上面的例子中,第二个数据段是第一个数据段的后续,汇编程序把它们是合二为一,上述的代码段也如此。

 

下面,详细说明段属性的含义及其作用。

 

4.1 对齐类型

对齐类型表示当前段对起始地址的要求,连接程序(LINK.EXE)按下表的地址格式来定位段的起始地址。在进行段定位时,会根据其定位类型进行定位的,所以,各段之间就有可能出现一些空闲字节,即可能浪费几个字节单元。

 

段对齐类型PARA是一个适用于所有段类型的对齐类型,它也是缺省的对齐类型。对齐类型BYTEWORD通常用于数据段的定位,对齐类型DWORD通常用于80386及其以后CPU代码段的定位。

 

对齐类型 起始地址(二进制) 功能说明 最多的空闲字节数

BYTE xxxx xxxx xxxx xxxx xxxx 下一个字节地址  0

WORD xxxx xxxx xxxx xxxx xxx0 下一个字地址  1

DWORD xxxx xxxx xxxx xxxx xx00 下一个双字地址  3

PARA xxxx xxxx xxxx xxxx 0000 下一个节地址 15

PAGE xxxx xxxx xxxx 0000 0000 下一个页地址 127

 

4.2 组合类型

组合类型是告诉连接程序如何把不同模块中段名相同的段合并在一起。具体的组合类型如下:

 

NONE 表示当前段在逻辑上独立于其它模块,并有其自己的基地址。NONE是缺省的组合类型。

 

PUBLIC 表示当前段与其它模块中同段名的PUBLIC类型段组合成一个段。组合的先后次序取决于LINK程序中目标模块排列的次序。在组合时,后续段的起始地址要按其对齐类型进行定位,所以,同名段之间可能有间隔。

 

COMMON 表示当前段与其它模块中同名段重叠,也就是说,它们的起始地址相同。最终段的长度是同名段的最大长度。由于段覆盖,所以,前一同名段中的初始化数据被后续段的初始数据覆盖掉。

 

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

AT 数值表达式 该数值表达式是当前段所指定的绝对起始地址的段地址。

 

4.3 类别与段组

类别是一个由程序员指定的用单引号括起来的字符串。如果一个段没有给出类别,那么,这个段的类别就为空。类别是用于段的分类,连接程序利用该类别来调整同名、同类别的段,并使它们相邻。典型的类别是"Data""Code"。如果指定某段的类别是"Code",那么,该段最好是代码段,这样,有的调试程序(如:CodeView)就可以顺序工作。

 

例如:

DATA1 SEGMENT  WORD  PUBLIC  "Data"

DATA1 ENDS

 

上述段定义说明了该段的起始地址是下一个字地址、组合类型为PUBLIC、段类别是"Data"

 

段组伪指令GROUP是用于把源程序模块中若干个段结合成一个组,并对该段组定义一个段组名。段组伪指令的格式如下:

 

段组名  GROUP  段名[, 段名, ……]

 

其中:段名之间要用逗号间隔,段名也可以用表达式“SEG 变量”或“SEG 标号”。

 

下面举例说明段组伪指令的使用方法和作用。

 

例,段组的作用

方法1:用一个段寄存器对应二个数据段

DATA1 SEGMENT ;第一个数据段

b1 DB 10h

DATA1 ENDS

DATA2 SEGMENT ;第二个数据段

b2 DB 23h

DATA2 ENDS

CODE1 SEGMENT

ASSUME CS:CODE1, DS:DATA1 ;(1)

START: MOV AX, DATA1

MOV DS, AX  ;(2)把数据段DATA1的段值赋给段寄存器DS

MOV BL, b1 ;(3)引用DS来访问DATA1中的变量b1

ASSUME DS:DATA2 ;(4)

MOV AX, DATA2

MOV DS, AX ;(5)把数据段DATA2的段值赋给段寄存器DS

MOV AL, b2 ;(6)引用DS来访问DATA2中的变量b2

CODE1 ENDS

END START

 

在上例中,语句(1)说明DSDATA1建立联系,语句(2)DS赋值,语句(3)DS来访问DATA1段的变量名。语句(4)说明DSDATA2建立联系,语句(5)DS赋值,语句(6)DS来访问DATA2段的变量名。

 

在该例子中,因为只使用一个段寄存器DS来对应二个数据段,所以,需要切换DS的对应关系(如:语句(4))。但我们也可以用段寄存器DSES来分别对应段DATA1DATA2,这样,方法1就可变成方法2

 

方法2:用二个段寄存器对应二个数据段:

DATA1 SEGMENT

b1 DB 10h

DATA1 ENDS

DATA2 SEGMENT

b2 DB 23h

DATA2 ENDS

CODE1 SEGMENT

ASSUME CS:CODE1, DS:DATA1, ES:DATA2

START: MOV AX, DATA1

MOV DS, AX  ;把数据段DATA1的段值赋给段寄存器DS

MOV AX, DATA2

MOV ES, AX ;把数据段DATA2的段值赋给段寄存器ES

MOV BL, b1 ;引用DS来访问DATA1中的变量b1

MOV AL, b2 ;引用ES来访问DATA2中的变量b2

CODE1 ENDS

END START

 

我们还可以用段组来简化段寄存器的使用把段DATA1DATA2组成一个数据段。所以,把方法2再改写成方法3的形式。

 

方法3:用一个段组组成二个数据段

 

 GSEG GROUP DATA1, DATA2 ;把段DATA1DATA2定义成一个段组

DATA1 SEGMENT

 b1 DB 10h

DATA1 ENDS

DATA2 SEGMENT

b2 DB 23h

DATA2 ENDS

CODE1 SEGMENT

ASSUME CS:CODE1, DS:GSEG

START: MOV AX, GSEG

MOV DS, AX  ;把段组GSEG的段值赋给段寄存器DS

MOV BL, b1 ;引用DS来访问DATA1中的变量b1

MOV AL, b2 ;引用DS来访问DATA2中的变量b2

CODE1 ENDS

END START

 

定义段组后,段组内各段所定义的标号和变量,除了与定义它们的段起始点相关外,还与段组的起始点相关。规定如下:

 

l         如果在ASSUME伪指令中说明段组与段寄存器相对应,那么,有关标号或变量的偏移量就相对于段组起点计算;

l         如果在ASSUME伪指令中说明段组内的某各段与段寄存器相对应,那么,有关标号或变量的偏移量就相对于该段的起点。

 

所以,在使用段组后,程序员要谨慎使用ASSUME伪指令,并保证段寄存器的值与段组或段相一致。

相关文章推荐

Intel汇编语言程序设计学习-第二章 IA-32处理器体系结构-下

Intel汇编语言程序设计学习-第二章 IA-32处理器体系结构-下

《Windows环境下32位汇编语言程序设计(第2版)》-chapter17知识点

今天又重新回到PE文件的学习了,之前学的Win32汇编更多是的利用API函数进行桌面程序的开发,PE文件这涉及到很多底层的东西,感觉是块儿硬骨头很难啃,不过还是得学下去。今天又关注了一下安全行业的发展...

Intel汇编语言程序设计学习-第五章 过程-下

Intel汇编语言程序设计学习-第五章 过程-下

intel汇编语言程序设计 后面编程

5.3 TITLE Add and Subtract; This program adds and subtracts 32-bit integers.; Last update: 06/01/200...

《Inter汇编语言程序设计》10.1.1 结构中域的对齐(ALIGN伪指令)

(这是一个为win32汇编结构体中域的内存对齐的理解) 内存对齐:        现代计算机中内存空间都是按照byte划分的,从理论上讲似乎对任何类型的变量的访问可以从任何地址开始,但实际情况是在...
  • yss28
  • yss28
  • 2013年04月09日 17:33
  • 653

汇编语言程序设计——仿win7计算器(功能部分)

下面代码实现的计算机基本的功能,包括加、减、乘、除、求倒、开方、百分比、记忆相关功能等,支持快捷键,显示也可以分段显示,如下图。             界面部分源码:http://blog.csd...

汇编课后习题2.14《32位汇编语言程序设计》

任务是打ASCII 我用了三个h

新版汇编语言程序设计【课后习题答案】

新版汇编语言程序设计【课后习题答案】 钱晓捷 主编 电子工业出版社 第2章 8086的指令系统(全)答案集锦2010-10-18 20:23:47阅读842评论1  字号:大中小 订阅第2章 8086...

第一讲 - WIN32基础知识-WIN32汇编语言程序设计001

必须了解的基础知识 (来自鱼C工作室) 本教程对应视频:WIN32汇编语言程序设计视频下载 80x86 处理器的工作模式 实模式 ...
  • fish_c
  • fish_c
  • 2011年08月12日 16:48
  • 3147

汇编语言程序设计学习笔记(第一遍学习)-第4节:汇编就像HTML一样简单

最近好多天没有更新笔记了,主要是最近几个月在写操作系统,比较忙点了,大约要写3个月左右呢,因为我学习的安排也会顺着兴趣随时做一些小的改动,因为兴趣是最好的老师嘛!今天在写操作系统之余再更新汇编的学习笔...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:汇编语言程序设计(五)
举报原因:
原因补充:

(最多只允许输入30个字)