汇编语言中段的定义
汇编语言中段的完整定义
形式:
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伪指令允许用户自行指定段组。

Leave a comment