在FASM中定义结构 - 在哪种情况下,哪两种方式更好

问题描述 投票:1回答:1

在FASM中,有两种方法可以定义结构:

struc point x, y, z
{
    .x db x,
    .y db y,
    .z db z
}

struct POINT
    x db ?
    y db ?
    z db ?
ends 

我什么时候应该使用哪个?

assembly fasm
1个回答
1
投票

The short answer:

使用struct/ends

Explanation:

这两种结构相似,但仍有本质区别。

struc指令:

第一个使用struc指令。它与macro指令非常相似,只是创建了一个结构模板。但是在您创建此模板的“实例”之前,它实际上并不存在。以下示例将编译为错误:

 struc POINT {
   .x dd ?
   .y dd ?
 }

mov eax, [esi+POINT.x]

另一方面,以下代码将正确编译:

struc POINT {
  .x dd ?
  .y dd ?
}
myPoint POINT

mov eax, [myPoint.x]

但这不会:

lea esi, [myPoint]
mov eax, [esi+POINT.x]

上例中的POINT只是一个模板,但不是具有定义的偏移量,大小等的结构。

struct / ends宏:

创建宏struct/ends是为了解决struc指令的上述缺点。除了创建模板外,他们还会在地址0处创建此模板的实例,并在sizeof中创建标签。地址空间,包含结构的大小。

下面的struct定义......

struct POINT
  .x dd ?
  .y dd ?
ends

...(大约)等于以下原始定义:

struc POINT {
  .x dd ?
  .y dd ?
}

virtual at 0
  POINT POINT
  sizeof.POINT = $ - POINT
end virtual

这就是我们同时拥有模板和真实偏移标签的原因。使用struct以上所有示例代码都将正确编译:

struct POINT
  .x dd ?
  .y dd ?
ends

myPoint1 POINT
myPoint2 POINT

lea esi, [myPoint1]

mov eax, [esi+POINT.x]
mov [myPoint2.x], eax
mov ecx, sizeof.POINT

请注意,上述“等同”代码仅用于说明。 struct宏的真正实现可能不同。例如,FreshLib库使用上述方法,而FASM宏库使用另一个,以避免字段名称中的点,并实现更多功能,如字段初始化等。

但最终结果或多或少相等加/减小细节。

© www.soinside.com 2019 - 2024. All rights reserved.