Определение структуры в FASM - какой из двух способов лучше в какой ситуации
В FASM есть 2 способа определения структуры:
struc point x, y, z
{
.x db x,
.y db y,
.z db z
}
а также
struct POINT
x db ?
y db ?
z db ?
ends
Когда я должен использовать что?
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]
ТОЧКА в приведенном выше примере - это просто шаблон, но не структура с определенными смещениями, размерами и т. Д.
Структура / заканчивается макросами:
Макросы struct/ends
созданы для того, чтобы исправить вышеуказанные недостатки struc
директивы. Помимо создания шаблона, они также создают экземпляр этого шаблона по адресу 0 и метку в размере. адресное пространство, содержащее размер структуры.
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 использует другой, чтобы избежать точек в именах полей и реализовать больше функций, таких как инициализация полей и т. Д.
Но конечный результат более или менее равен плюс / минус мелких деталей.