Структуры

Последнее обновление: 02.07.2023

Ассемблер 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
Помощь сайту
Юмани:
410011174743222
Перевод на карту
Номер карты:
4048415020898850