MASM提供SEGMENT指令。该指令采用了几个参数。 use
参数可以取值FLAT
。我不清楚这个价值是做什么的。
Microsoft docs将其指定为可接受的值,但不要尝试描述它:
使用
USE16 , USE32 , FLAT
在线提供的书籍The Art of Assembly Language Programming提到它,但称其超出范围并建议阅读MASM程序员指南:
use32
和flat
操作数告诉MASM为32位段生成代码。由于本文不涉及保护模式编程,因此我们不会考虑这些选项。有关详细信息,请参阅MASM程序员指南。
在Microsoft的MASM 6.1程序员指南中,在描述SEGMENT
指令的部分中,提到了FLAT
值,但从未描述过它的影响:
尺寸属性可以是 USE16 , USE32 或 FLAT 。
FLAT操作数对SEGMENT指令有什么影响?
答案 0 :(得分:5)
对于大多数用途,在段指令中使用FLAT关键字与USE32具有相同的含义。 USE32和FLAT关键字都表明该段可以大于64K,并且在段中组装的任何指令都应该使用32位编码而不是16位编码。区别在于汇编程序对CS寄存器的假设。通常情况下,SEGMENT指令会生成隐式ASSUME CS:xxx
指令,其中xxx
是段的名称,但使用FLAT会导致隐式ASSUME CS:FLAT
。
ASSUME指令告诉汇编器将哪些段加载到哪个段寄存器中,以便它可以在需要时自动使用正确的段覆盖。在大多数32位操作系统使用的平面存储器模型中,只有一个4千兆字节的段。告诉汇编程序可以通过该段寄存器访问程序中定义的所有段,告诉汇编程序它可以采用段寄存器。例如ASSUME DS:FLAT
表示可以通过DS寄存器访问所有段。另一方面,ASSUME DS:_DATA
表示DS寄存器只能用于访问_DATA段而不能用于访问任何其他段。
您可以通过汇总以下代码来查看此行为:
_DATA SEGMENT PUBLIC USE32
var DD ?
_DATA ENDS
_TEXT SEGMENT PUBLIC PARA 'CODE' FLAT
mov eax, [zero]
mov [var],eax
ASSUME DS:FLAT
mov eax, [zero]
mov [var],eax
ASSUME CS:_TEXT
ASSUME DS:_DATA
mov eax, [zero]
mov [var],eax
zero DD 0
_TEXT ENDS
END
如果您反汇编生成的目标文件,您会看到前两条指令:
00000000: 2E A1 00 00 00 00 mov eax,dword ptr cs:[zero]
00000006: 2E A3 00 00 00 00 mov dword ptr cs:[var],eax
对于这两条指令,汇编程序必须使用CS段覆盖(2E
)才能访问zero
和var
。这是因为虽然汇编程序知道CS可用于访问所有段,包括_TEXT
和_DATA
,但它并不知道可以使用任何其他段寄存器来访问这些semgents。
这是在ASSUME DS:_FLAT
指令之后为下两条指令生成的代码:
0000000C: A1 00 00 00 00 mov eax,dword ptr [zero]
00000011: A3 00 00 00 00 mov dword ptr [var],eax
现在汇编程序知道CS和DS都可以用来访问所有段。由于使用DS访问zero
和var
并不需要段覆盖,因此它使用DS代替CS,从而导致更短的指令。
最后,在ASSUME DS:_DATA
和ASSUME CS:_TEXT
指令之后的最后两条指令显示了如果根本不使用FLAT关键字,汇编器将生成的代码:
00000016: 2E A1 00 00 00 00 mov eax,dword ptr cs:[zero]
0000001C: A3 00 00 00 00 mov dword ptr [var],eax
在这种情况下,汇编程序假设CS只能用于访问_TEXT,而DS只能用于访问_DATA。它必须使用CS覆盖来访问zero
,而它只能通过DS访问var
,这不需要分段覆盖。
注意如果在上面的示例代码中将SATMENT指令中的FLAT更改为USE32,则第一条指令最终使用CS覆盖,但第二条指令会产生以下错误:
error A2074:cannot access label through segment registers
那是因为虽然汇编程序知道它可以通过CS寄存器访问_TEXT,但它并不知道它可以用来访问_DATA的任何段寄存器。
如果您在代码开头使用.MODEL FLAT
指令,则不必担心任何此类指令。然后USE32和FLAT在段指令中具有完全相同的效果,因为假定每个段寄存器都是FLAT。