汇编语言中段的定义

2009-03-11 21:53 / no comment / 61 views /

汇编语言中段的完整定义

形式:
name SEGMENT [align] [READONLY] [combine] [use] ['class']

参数意义:
1、READONLY 只读属性,如果该段设置了只读属性,该段的数据只能读,一般用来存放常数,不过在实际使用中,基本没有人设置这个属性。
2、对齐 这里的对齐是指段的起始地址对齐的方式,可选值为(BYTE, WORD, DWORD, PARA, PAGE)
BYTE  —- 下一个字节地址    1 
WORD  —- 下一个字地址      2 
DWORD —- 下一个双字地址    4 
PARA  —- 下一个节地址    16 
PAGE  —- 下一个页地址    128 或 256
3、组合类型(combine)  组合操作影响链接器(link.exe)工作,组合类型如下(组合类型多使用在多模块场合,例如你有2个以上的asm文件,每个文件中都有段的设置,组合类型指示链接器如何将这些段重新组合,例如A.asm和B.asm中都有Data数据段,在链接这两个asm编译后的obj文件时,将这两个段组合成一个段还是分为两个段):
PRIVATE  PRIVATE属性指示链接器将每个段独立存放,即使它们拥有有万全相同的段名。
PUBLIC  PUBLIC属性指示链接器将所有的同名段连接成一个连续的完整的段。一个程序模块可以由若干段组成,段名可以各不相同,也可以重复,汇编程序将一个程序中的同名段处理成一个段。段的定义还可以嵌套,但不能交叉。
STACK    STACK属性指示链接器将同名的堆栈段连接成一个完整的堆栈段。
COMMON  COMMON属性指示链接器将所有的同名段重叠,即它们的起始地址相同,长度为其中最大长度的那个段。由于段覆盖,所以,前一同名段中的初始化数据被后续段的初始数据覆盖掉。 MEMORY  MEMORY和PUBLIC同义。
AT address AT属性不能使用在保护模式,address告诉链接器生成段的段地址。AT address所指示的段中不能包含有任何代码和初始化数据,通过结构或变量或矢量指出远程内存中的位置,便于用户在代码中远程访问或调用位于这些内存中的数据或代码。
4、use  use属性指出段的长度。使用类型只有对使用.386及以上处理器选择伪指令的段才起作用。它包括如下两种类型。
USE16指明该段为16位段,段的长度最大为64KB,地址的形式是16位段地址和16位偏移地址,寻址方式为16位寻址方式;USE32指明该段为32位段,段的长度最大为4GB,地址的形式是16位段地址和32位偏移地址,寻址方式为32位寻址方式。
如果该段未使用“使用类型”,而又使用.386及以上处理器选择伪指令,则汇编程序默认该段为32位段。
在实方式和虚拟8086方式中段的大小只能为64KB,因此,运行.386以上处理器选择指令的汇编源程序必须使用USE16。只有在保护方式下才使用32位段。
5、class  class属性指示链接程序按何种规则对段进行排序。缺省为.SEG:
.SEG  .SEG属性指示链接器段地址按照用户在代码中给出的顺序排序。
.ALPHA  .ALPHA属性指示链接器段地址按字母顺序排序。
.DOSSEG  .DOSSEG属性指示链接器按照MS-DOS的惯例排序。两个模块中的调用不能使用.DOSSEG属性。 
.DOSSEG 指示链接器按下面方式排序: 
1.代码段 
2.数据段按如下顺序:
    a.不是BSS或STACK属性的数据段
    b. BSS数据段
    c.STACK数据段

关于”LINK : warning L4021: no stack segment”警告的一个例子

问题

i have a “HOW ARE YOU !” program:

Code:

.386
DATA    SEGMENT USE16
BUF     DB “HOW ARE YOU !$”
DATA    ENDS

STACK   SEGMENT USE16
        DB 200 DUP(0)
STACK   ENDS

CODE    SEGMENT USE16
        ASSUME CS:CODE,DS:DATA,SS:STACK
START:  MOV AX,DATA
        MOV DS,AX
        LEA DX,BUF
        MOV AH,9
        INT 21H
        MOV AH,4CH
        INT 21H
CODE    ENDS
        END START

i cmd like this:

Code:

C:\masm32\bin>ml /c howareyou.asm
Microsoft (R) Macro Assembler Version 6.14.8444
Copyright (C) Microsoft Corp 1981-1997.  All rights reserved.

Assembling: howareyou.asm

C:\masm32\bin>link16 howareyou.obj;

Microsoft (R) Segmented Executable Linker  Version 5.60.339 Dec  5 1994
Copyright (C) Microsoft Corp 1984-1993.  All rights reserved.

LINK : warning L4021: no stack segment

C:\masm32\bin>howareyou
HOW ARE YOU !
C:\masm32\bin>

i have already assumed “SS:STACK”
but i get a  “no stack segment” warning when i link it
can anyone tell me why?
thank you!

回答

The linker is apparently looking for the combine type STACK. The syntax is:

name SEGMENT [align] [READONLY] [combine] [use] ['class']

So this should work:

STACK SEGMENT STACK USE16

Also, for ML 6.0 and later it’s not necessary to specify ASSUME CS:CODE.

堆栈段在segment后面必须加上stack声明,不然没用

存储模型与简化段定义伪指令

1.存储模型伪指令

存储模型的作用是什么呢?存储模型决定一个程序的规模,也确定进行子程序调用、指令转移和数据访问的缺省属性(NEAR或FAR)。当使用简化段定义的源程序格式时,在段定义语句之前必须有存储模型 .MODEL语句,说明在存储器中应如何安放各个段。

MODEL伪指令的常用格式如下:
.MODEL 存储模型

存储模型

功 能

适用操作系统

Tiny (微型)所有数据和代码都放在一个段内,其访问都为NEAR型,整个程序≤64K,并会产生.COM文件。MS-DOS
Small (小型)所有代码在一个64KB的段内,所有数据在另一个64KB的段内(包括数据段,堆栈段和附加段)。MS-DOS
Windows
Medium (中型)所有代码>64K时可放在多个代码段中,转移或调用可为FAR型。所有数据限在一个段内,DS可保持不变。MS-DOS
Windows
Compact(紧凑型)所有代码限在一个段内,转移或调用可为NEAR型。数据>64K时,可放在多个段中。MS-DOS
Windows
Large (大型)允许代码段和数据段都可超过64K,被放置在有多个段内,所以数据和代码都是远访问。MS-DOS
Windows
Huge (巨型)单个数据项可以超过64K,其它同Large模型MS-DOS
Windows
Flat (平展型)所有代码和数据放置在一个段中,但段地址是32位的,所以整个程序可为4GB。MASM 6.0支持该模型。OS/2
WindowsNT

注意:Small 模型是一般应用程序最常用的一种模型,因为只有一个代码段和一个数据段,所以数据和代码都是近访问的。这种模型的数据段是指数据段、堆栈段和附加段的总和。

在DOS下用汇编语言编程时,可根据程序的不同特点选择前6种模型,一般可以选用SMALL模型。另外,TINY模型将产生COM程序,其他模型产生EXE程序。FLAT模型只能运行在32位x86 CPU上,DOS下不允许使用这种模型。当与高级语言混合编程时,两者的存储模型应当一致。

2. 简化的段伪指令

  简化的段定义语句书写简短,语句.CODE、.DATA和.STACK分别表示代码数据段和堆栈段的开始,一个段的开始自动结束前面一个段。采用简化段指令之前必须有存储模型语句.MODEL。

简化段伪指令

功 能

注释

.CODE [段名]创建一个代码段段名为可选项,如不给出段名,则采用默认段名。对于多个代码段的模型,则应为每个代码段指定段名。
.DATA创建一个数据段段名是:_DATA
.DATA?创建无初值变量的数据段段名是:_BSS
.FARDATA [段名]建立有初值的远调用数据段可指定段名,如不指定,则将以FAR_DATA命名。
.FARDATA? [段名]建立无初值的远调用数据段可指定段名,如不指定,则将以FAR_BSS命名。
.CONST建立只读的常量数据段段名是:CONST
.STACK [大小]创建一个堆栈段并指定堆栈段大小段名是:stack。如不指定堆栈段大小,则缺省值为1KB

3.与简化段定义有关的预定义符号

汇编程序给出了与简化段定义有关的一组预定义符号,它们可在程序中出现,并由汇编程序识别使用。有关的预定义符号如下:
  (1)@code 由.CODE 伪指令定义的段名或段组名。
  (2)@data 由.DATA 伪指令定义的段名,或由 .DATA 、.DATA?、
    .CONST和 .STACK所定义的段组名。
  (3)@stack 堆栈段的段名或段组名。

段组定义伪指令

段组定义伪指令能把多个同类段合并为一个64KB的物理段,并用一个段组名统一存取它。段组定义伪指令GROUP的格式如下:
段组名 GROUP 段名 [, 段名 …]

我们已经知道在各种存储模型中,汇编程序自动地把各数据段组成一个段组DGROUP,以便程序在访问各数据段时使用一个数据段寄存器DS,而GROUP伪指令允许用户自行指定段组。

Get a Trackback link

No Comments Yet

You can be the first to comment!

Leave a comment

XHTML: You can use these tags: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>