3.1程序的段结构伪指令:SEGMENT和ENDS


3.1程序的段结构

  • 8086/8088将内存按逻辑段进行管理,不同的逻辑段可以用来存放不同目的的内容
  • 在程序中使用四个段寄存器CS, DS, ES和SS来访问它们。【80386以后,扩展段MS、GS等】
  • 源程序中,使用伪指令来定义和使用这些逻辑段

定义段的伪指令:SEGMENT和ENDS

  • 伪指令SEGMENT和ENDS用于定义一个逻辑段
  • 使用时必须配对,分别表示定义的开始与结束
  • 在定义一个段时,段名是必不可缺的项,而定位类型、组合类型和类别名三个参数是可选项。
    • 各个参数之间用空格分隔。各参数之间的顺序不能改变。

一般格式:

段名	SEGMENT [定位类型] [组合类型] [类别名'l
	……………………
段名	ENDS

段指令语句的各部分

段名

  • 由用户自己任意选定,但要符合标识符定义规则
  • 最好选用与该逻辑段用途相关的名称。如第一个数据段为DATA1,第二个数据段为DATA2等。
  • 配对的一对SEGMENT和ENDS前的段名必须一致

定位类型

  • 用于决定段的起始数据边界,即第一个可存放数据的位置(不一定是段基地址)。

  • 4种取值。段基地址不一定与起始数据边界重合

    • PARA:表示该段从一个小节的边界开始存放数据

      • 如果用户未选定位类型,则缺省(默认)为PARA;
      • 其段起始地址的最后4位二进制数一定为0,即以0H结尾的地址。
    • PAGE:表示该段从一个页面的边界开始存放数据

      • 由于一个页面为256个字节,并且页面编号从0开始
      • 因此,PAGE定位类型的段起始地址的最后8位二进制数一定为0,即以00H结尾的地址。
    • WORD:表示该段从一个偶数字节地址开始存放数据,即段起始数据单元地址的最后一位二进制数一定是0。

    • BYTE:表示该段起始数据单元地址可以是任一地址值

组合类型

  • 用来指定段与段之间的连接关系和定位

  • 它有六种取值选择。

    • 未指定组合类型,表示本段与其它段无连接关系。在装入内存时,本段有自己的物理段,因此有自己的段基址【默认使用】

    • STACK:把所有同名段连接成一个连续段,且系统自动对SS段寄存器初始化为该连续段的段基址,并初始化堆栈指针SP。

      • 用户程序中应至少有一个段用STACK说明,否则需要用户程序自己初始化SS和SP。
    • PUBLIC:在满足定位类型的前提下,将与该段同名的段邻接在一起,形成一个新的逻辑段,共用一个段基址。段内的所有偏移量调整为相对于新逻辑段的段基址。

    • COMMON:产生一个覆盖段。在多个模块连接时,把该段与其它也用COMMON说明的同名段置成相同的段基址,这样可达到共享同一存储区。共享存储区的长度由同名段中最大的段确定

    • AT:表示本段可定位在表达式所指示的小节边界上。表达式的值也就是段基值

    • MEMORY:表示本段在存储器中应放在所有其它段之后的位置(最高地址)

      • 如果有多个用MEMORY说明的段,则只处理第一个用MEMORY说明的段,其余的被视为COMMON。

类别名

  • 类别名为某一个段或几个相同类型段设定类型名称
  • 系统在进行连接处理时,把类别名相同的段存放在相邻的存储区,但段的划分与使用仍按原来的设定
  • 类别名必须用单引号引起来。所用字符串可任意选定,但它不能使用程序中的标号、变量名或其它定义的符号。

例:分段结构的源程序框架

STACK1 SEGMENT PARA STACK 'STACK0'
		…………
STACK1 ENDS
DATA1 SEGMENT PARA 'DATA'
		…………
DATA1 ENDS
STACK2 SEGMENT PARA 'STACK0'
		…………
STACK2 ENDS

CODE SEGMENT PARA MEMORY
ASSUME CS:CODE,DS:DATA1,SS:STACK1
MAIN:
		…………
CODE ENDS

DATA2 SEGMENT BYTE 'DATA'
		…………
DATA2 ENDS
	END MAIN

上述源程序经LINK程序进行连接处理后,程序被装入内存的情况如图所示。