Ассемблер MASM позволяет определять структуры - составные типы данных, которые состоят из элементарных типов. Для определения структуры применяется слово struct:
название_структуры struct поля структуры название_структуры ends
Сначала идет название структуры, затем слово struct
. Далее идут переменные структуры (еще назваются полями) - те элементы, из которых состоит структуры.
Завершается определение структуры также названием структуры, за которым следует слово end
. Например:
point struct ; структура представляет точку x word ? ; координата Х y word ? ; координата Y point ends
Здесь определена структура point, которая условно представляет точку. В этой структуре определено два поля. Поля определяются также как и обычные переменные. Первая переменная представляет координату X, а вторая переменная - координату Y. Обе переменных представляют тип word.
Структура можно определяться в любом месте программы до своего использования. Затем мы можем определить переменную этой структуры, например, в секции .data
.data center point {}
Здесь определена переменная center, которая представляет структуру point. Для определения переменной структуры применяются фигурные скобки {}
.
При обращении к полям структуры следует понимать, что в памяти поля структуры располагаются рядом в том порядке, в котором они определены. Для доступа к полю структуры применяется имя переменной структуры (которое по сути представляет адрес структуры) и смещение поля относительно начала структуры. Например:
center[0] или center ; обращение к полю Х center[2] ; обращение к полю y
Поскольку поле x - переменная типа word и занимает 2 байта, то смещение поля y относительно начала структуры будет 2 байта. Пример полностью:
point struct ; структура представляет точку x word ? ; координата Х y word ? ; координата Y point ends .data center point {} .code main proc mov center[0], 5 ; устанавливаем значения полей mov center[2], 4 xor rax, rax mov ax, word ptr center[2] ; EAX = 4 ret main endp end
При передаче данных из регистра требуется привести поле структуры к типу регистра:
mov rax, 5 mov word ptr center, ax
Несмотря на то, что поле x структуры point представляет тип word, но все равно преобразуем данные в тип word, поскольку получаем данные из 16-разрядного регистра ax.
Поскольку манипулировать смещениями тех или иных полей не очень удобно, особенно когда полей довольно много, то MASM позволяет обращаться к полям по их имени:
имя_структуры.имя_поля
Например:
point struct ; структура представляет точку x word ? ; координата Х y word ? ; координата Y point ends .data center point {} .code main proc mov rdx, 5 mov center.x, 6 mov center.y, dx xor rax, rax mov ax, word ptr center.y ; EAX = 5 ret main endp end
При определении переменной структуры можно сразу инициализировать ее поля, передав им значения в фигурных скобках:
.data center point {10, 15}
Здесь x=10, а y=15.
Если поле структуры - набор, то значения этого набора указываются в фигурных скобках:
list struct elements byte 5 dup(?) list ends .data numbers list {{3, 4, 5, 6, 7}} .code main proc xor rax, rax mov al, byte ptr numbers[2] ; EAX = 5 ret main endp end
Также из структур можно создавать массив:
point struct ; структура представляет точку x word ? ; координата Х y word ? ; координата Y point ends .data ;points point 3 dup ({}) ; массив из трех точек points point{1, 2} point {3, 4} point {5,6} .code main proc mov rax, 9 lea rbx, points mov [rbx + 2*4], al ; обращаемся к координате x третьей точкb movzx rax, word ptr [rbx + 2*4] ; AX = 9 ret main endp end
В данном случае определяется массив из трех точек - структур point. Для обращения к точкам в регистр RBX загружаем адрес массива points. Каждый элемент point в
массиве занимает 4 байта (по 2 байта на каждую координату). Поэтому чтобы обратиться к адресу координаты x третьей точки, применяется выражение
[rbx + 2*4]
. Соответственно для обращения к координате y этой точки, надо к этому адресу прибавить еще 2 байта: [rbx + 2*4+2]
Также можно определять неинициализованный массив структур:
.data points point 3 dup ({}) ; массив из трех точек
Для более быстрого обращения к полям структуры можно использовать выравнивание, которое устанавливается с помощью директивы align. Например
point3D struct ; структура представляет точку в пространстве x byte ? ; координата Х y byte ? ; координата Y z byte ? ; координата Z point3D ends
Переменная y здесь будет располагаться по нечетному адресу. Применим выравнивание:
point3D struct ; структура представляет точку x byte ? ; координата Х align 2 ; выравнивание по двум байтам y byte ? ; координата Y z byte ? ; координата Z point3D ends
Теперь переменная x будет выравнена по 2 байтам - после нее добавляется еще один байт.
Также можно сразу задать выравнивание для всех переменных в определении структуры:
point3D struct 2 ; выравнивание всех переменных по двум байтам x byte ? y byte ? z byte ? point3D ends