MASM SEG 操作符

4
假设我们正在使用MASM 6.1 / 16位/大型数据模型编写汇编代码,并且有一个名为MY_VAR的变量(标签),一个名为MY_SEG的段和一个名为MY_GROUP的段组。假设MY_VAR放置在MY_SEG中,而MY_SEG属于MY_GROUP。
那么,以下两个语句有什么区别:
1) MOV AX, MY_SEG
2) MOV AX, SEG MY_SEG:MY_VAR

此外,以下两个语句有什么区别?
请注意,保留了HTML标签。
1) MOV AX, MY_GROUP
2) MOV AX, SEG MY_GROUP:MY_VAR

注意:MASM可以愉快地处理所有这些语句。如预期(在我的情况下),1)和2)的结果相同。但我想确切地知道...
非常感谢, Binarus
1个回答

3
在MASM中,标签MY_VAR被翻译为相对于声明它的段的地址偏移量(如果您像mov ax, MY_VAR这样使用它),或者相对于您用于访问它的段寄存器所假定的段(如果您像mov ax, WORD PTR [MY_VAR]这样使用它)。
如您所知,给定变量(一般为线性地址)有多个逻辑地址,例如在8000h线性处的变量可以作为0800h:0000h0700h:1000h等进行访问。
形式MY_SEG:MY_VAR告诉汇编器计算相对于段MY_SEG的偏移量。因此,如果MY_SEG在线性起始于7000h,MY_SEG2在线性起始于6000h,则位于线性8000h处的变量MY_VAR的MY_SEG:MY_VAR为1000h,MY_SEG2:MY_VAR为2000h。 SEG指令计算逻辑地址的段部分而不是偏移量,它是MASM用于计算偏移量的段(再次根据上述规则)。
在您的第一条指令中,您告诉MASM将段MY_SEG的地址(忽略重定位)放入AX中(因此,如果该段从5000h开始,则AX中的值为500h)。
在第二条指令中,您明确告诉MASM在计算MY_VAR的偏移量时使用MY_SEG段,然后通过SEG指令告诉它返回段部分,即MY_SEG
因此,它们是相同的,但第二个是多余的。

我一直认为MY_VAR在语法上等同于OFFSET MY_VAR。如果我是正确的(可能我不是),这意味着在MASM 5中,MY_VAR被翻译为相对于段的偏移量,但在MASM 6中,它被翻译为相对于组的偏移量。你能否在这里添加更多细节(并纠正我的错误假设)? - Binarus
@user3239842 我想这样做,但我没有 MASM 进行快速测试。据我所知,在 MASM 中,当您执行 mov ax,[MY_VAR] 时,汇编器会查找您已声明 MY_VAR 的段,并将其用于偏移计算。您必须使用 ASSUME 和 MY_VAR 的段,最终汇编器会生成一个段覆盖前缀。对于组,算法略有不同,请参见 此处。如果您使用 mov ax,MY_VAR,我认为偏移量始终相对于 MY_VAR 的段。 - user781847
谢谢提供的链接。这是一个很好且易于理解的总结,介绍了我曾经从MASM 6文档中艰难学到的知识。为消除歧义,现在我已经按照以下方式更改了所有独立汇编代码:不再存在没有有效ASSUME指令的地方,每当使用SEG或OFFSET时,符号名称都以限定形式给出,即MY_GROUP:MY_VAR或MY_SEG_MYVAR。我在内联汇编中仍然有一个相关问题,因为显然我们不能在那里使用ASSUME或合格的表示法,请参见此处 - Binarus
我使用限定形式进行所有寻址,例如 MOV AX,[DS:MY_VAR] 而不是 MOV AX, [MY_VAR]。再加上正确的 ASSUMES,我的代码现在应该是防弹的了。 - Binarus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接