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

时间:2017-01-25 05:01:32

标签: assembly fasm

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

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

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

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

1 个答案:

答案 0 :(得分:1)

答案简短:

使用struct/ends

说明:

这两种结构相似,但仍然存在本质区别。

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

请注意上述" equial"代码只是为了说明。 struct宏的实际实现可能有所不同。例如,FreshLib库使用上述方法,而FASM宏库使用另一个,以避免字段名称中的点,并实现更多功能,如字段初始化等。

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