我刚刚开始使用ASM和x8086架构,并且我遇到了一些跟随emu8086附带的一些示例的问题。
SSEG SEGMENT STACK 'STACK'
DW 100h DUP(?)
SSEG ENDS
好的 SSeg ,我猜它是一个标签作为堆栈段, SEGMENT 关键字表示前面是一个段,但{{1}是什么} 代表?
以下,我认为这意味着“分配(我不知道在哪里)100h 16位字,没有值”
这是正确的吗?如果是,那么它在哪里分配?
答案 0 :(得分:3)
我假设emu8086支持声明一个段,语法与TASM相同,后者支持与MASM相同的语法。
使用<name> SEGMENT [attributes]
或SEGMENT <name> [attributes]
声明细分受众群。 属性是可选的,如果缺少任何值,则推断出默认值。
<name>
可以是任何尚未定义的有效名称(请注意.MODEL
指令定义了某些名称,包括 _TEXT 和 _DATA )。
[attributes]
分为五个类别,每个类别都有一个或多个可供选择的值。
来自不同类别的值由空格分隔,不再是任何类别的单个值都可以出现。
细分组合属性
这些属性值定义了两个或多个段如何组合在一起。
PUBLIC
使链接器连接具有在不同模块(即源文件)中定义的相同名称的段。 PRIVATE
与上述相反,在当前模块之外定义的具有相同名称的段将不会连接(请注意,在同一文件段中具有相同名称的段仍被视为同一段)。 / LI>
STACK
与PUBLIC
相同,但在生成的二进制文件中,创建了元数据,以便操作系统使用此属性将SS:SP
设置为段的末尾(在连接发生后) MEMORY
是STACK
的别名和TASM手册中的拼写错误。 COMMON
具有相同名称的所有段将重叠而不是连接。最后一段与最长的COMMON
段一样长。VIRTUAL
用于声明必须在最终二进制文件中只出现一次的段,无论在所有模块中声明了多少次。AT
将细分受众群放置在特定地址。UNINIT
将该段标记为包含未初始化的数据(就像ELF中的.bss
部分一样)细分类别属性
这是一个代表字段类的带引号的字符串。 segment类是仅对链接器有意义的字符串,它有助于在最终二进制文件中创建元数据时排序和识别段的用途。
链接器识别的类包括:_TEXT
,FAR_DATA
,FAR_BSS
,_DATA
,CONST
,_BSS
和STACK
。< / p>
细分对齐属性
这些值指定了段必须具有的对齐方式
简而言之,它们告诉链接器一个段可以开始的多个,例如PARA
,对于段,16个字节,告诉链接器段可以从16的地址倍数开始: 0,16,32,48,......
BYTE
,对齐1 WORD
,对齐2 DWORD
,对齐4 PARA
,对齐16 PAGE
对齐256 MEMPAGE
对齐4096 细分受众群规模属性
这些值指定代码的大小和段的数据。
USE16
告诉汇编程序,要生成的代码必须是16位,并且访问的数据必须使用16位地址大小。USE32
与上述相同,但大小为32位。 细分访问属性
TLINK 不支持这些属性,告诉链接器该段的元数据中存在哪些访问限制。
这不适用于DOS二进制文件
值为EXECONLY
,EXECREAD
,READONLY
,READWRITE
。这些名字很有说服力。
细分定义SSEG SEGMENT STACK 'STACK'
定义了一个细分:
SSEG
。STACK
,使链接器发出元数据以将SS:SP
设置为指向它的结尾。'STACK'
使链接器将其识别为堆栈段。使链接器知道段是一个堆栈段是使用STACK
组合和'STACK'
类完成的。
第一个控制SS:SP
1 的初始值,并且足以有一个堆栈。
第二个指定段本身的排序和分组。
细分群组
链接器可以将段组合在一起,这就像连接段但尊重对齐约束一样 通过将段组合在一起,可以使用单个段寄存器来访问所有段 段分组还用于对段进行逻辑分组,即使链接器对它们进行相同的处理。
特别是,TASM隐含地定义了DGROUP
组,当使用.MODEL
指令时,其中包括具有类'DATA'
和'STACK'
的段。
您可以使用'STACK'
指令的DGROUP
选项从FARSTACK
中排除.MODEL
段。
因此,类'STACK'
告诉链接器该段必须(或不得进入)DGROUP
。
此外,该组'STACK'
段内放置在任何其他段类之后。
STACK 'STACK'
对的最终效果是:
SS:SP
。 DW 100h DUP(?)
行只是按照你说的去做,但正确的术语是 reserve ,因为我相信在二进制文件中没有为堆栈分配空间。链接器可能足够聪明,可以识别出具有未初始化数据的'STACK'
分段不需要在磁盘上进行。
但我可能错了,我不记得二进制文件的MZ标题是否允许这样做。
声明预定义大小的堆栈段的另一种更简单的方法是.STACK 200h
(如果使用1KiB堆栈,则只需.STACK
。)
Chapter 7 of the TASM manual有关于这个长话题的更完整信息。
1 为了更好地理解这一点,值得注意的是,生成的EXE有一个头,其中链接器可以指定这些寄存器的初始值,操作系统将重定位并设置它们加载二进制文件。