在FASM中,有两种方法可以定义结构:
struc point x, y, z
{
.x db x,
.y db y,
.z db z
}
和
struct POINT
x db ?
y db ?
z db ?
ends
我什么时候应该使用哪个?
答案 0 :(得分:1)
使用struct/ends
。
这两种结构相似,但仍然存在本质区别。
第一个使用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
是为了解决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宏库使用另一个,以避免字段名称中的点,并实现更多功能,如字段初始化等。
但最终结果或多或少等于加/减小细节。