程序集段声明语法

时间:2016-11-26 20:17:24

标签: assembly emu8086

我刚刚开始使用ASM和x8086架构,并且我遇到了一些跟随emu8086附带的一些示例的问题。

SSEG    SEGMENT STACK   'STACK'
DW      100h    DUP(?)
SSEG    ENDS

好的 SSeg ,我猜它是一个标签作为堆栈段, SEGMENT 关键字表示前面是一个段,但{{1}是什么} 代表?

以下,我认为这意味着“分配(我不知道在哪里)100h 16位字,没有值”
这是正确的吗?如果是,那么它在哪里分配?

1 个答案:

答案 0 :(得分:3)

我假设emu8086支持声明一个段,语法与TASM相同,后者支持与MASM相同的语法。

使用<name> SEGMENT [attributes]SEGMENT <name> [attributes]声明细分受众群。 属性是可选的,如果缺少任何值,则推断出默认值。

<name>可以是任何尚未定义的有效名称(请注意.MODEL指令定义了某些名称,包括 _TEXT _DATA )。

[attributes]分为五个类别,每个类别都有一个或多个可供选择的值。 来自不同类别的值由空格分隔,不再是任何类别的单个值都可以出现。

细分组合属性
这些属性值定义了两个或多个段如何组合在一起。

  • PUBLIC使链接器连接具有在不同模块(即源文件)中定义的相同名称的段。
  • PRIVATE与上述相反,在当前模块之外定义的具有相同名称的段将不会连接(请注意,在同一文件段中具有相同名称的段仍被视为同一段)。 / LI>
  • STACKPUBLIC相同,但在生成的二进制文件中,创建了元数据,以便操作系统使用此属性将SS:SP设置为段的末尾(在连接发生后)
  • MEMORYSTACK的别名和TASM手册中的拼写错误。
  • COMMON具有相同名称的所有段将重叠而不是连接。最后一段与最长的COMMON段一样长。
  • VIRTUAL用于声明必须在最终二进制文件中只出现一次的段,无论在所有模块中声明了多少次。
  • AT将细分受众群放置在特定地址。
  • UNINIT将该段标记为包含未初始化的数据(就像ELF中的.bss部分一样)

细分类别属性

这是一个代表字段类的带引号的字符串。 segment类是仅对链接器有意义的字符串,它有助于在最终二进制文件中创建元数据时排序和识别段的用途。
链接器识别的类包括:_TEXTFAR_DATAFAR_BSS_DATACONST_BSSSTACK。< / 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二进制文件 值为EXECONLYEXECREADREADONLYREADWRITE。这些名字很有说服力。

细分定义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'对的最终效果是:

  1. 初始化SS:SP
  2. 在数据之后放置堆栈。
  3. DW 100h DUP(?)行只是按照你说的去做,但正确的术语是 reserve ,因为我相信在二进制文件中没有为堆栈分配空间。链接器可能足够聪明,可以识别出具有未初始化数据的'STACK'分段不需要在磁盘上进行。
    但我可能错了,我不记得二进制文件的MZ标题是否允许这样做。

    声明预定义大小的堆栈段的另一种更简单的方法是.STACK 200h(如果使用1KiB堆栈,则只需.STACK。)

    Chapter 7 of the TASM manual有关于这个长话题的更完整信息。

    1 为了更好地理解这一点,值得注意的是,生成的EXE有一个头,其中链接器可以指定这些寄存器的初始值,操作系统将重定位并设置它们加载二进制文件。