Сложные структуры данных. Перечислимые типы данных. Прерывания пользователя, страница 3

Доступ к полям структуры осуществляется, как обычно это принято, путем указания имени переменной, имеющей данную структуру, и имени поля соединенными оператором точка «.»: C.Re или C.Im. При этом для формирования указанного таким образом эффективного адреса поля структуры ассемблер добавляет к смещению структуры смещение полей внутри структуры. Поскольку поле Re является первым полем структуры, то его смещение внутри структуры равно нулю, а смещение поля Im будет равно 4.

Для полей структуры может быть использована не только прямая, но и косвенная адресация:

Mov  bx,offset C

Mov  eax,[bx].Re

Для инициализации полей структуры начальными значениями, отличными от заданных по умолчанию, как и для случая записей можно воспользоваться двумя различными подходами. Первый: можно перечислить начальные значения, которые должны быть транслятором записаны в поля структуры, в порядке следования полей, заключив эти значения в угловые скобки. Второй: такие значения могут быть перечислены в произвольном порядке с указанием имен полей, но тогда они должны быть заключены в фигурные скобки.

С1    Complex    {Im=2.0}

Работая со структурами, следует иметь в виду, что в ассемблере определены и тип формата структуры, и тип переменной, имеющей этот формат. При этом, например, type Complex = type C = 8, в то же время, type C.Im = type C.Re = 4.

Ассемблер допускает описание и массивов структур, например:

Array Complex    <>, <1.0,1.0>, 10 dup <?,?>

8.6. Объединения

Если структура  предполагает последовательное расположение в памяти описанных в ней полей, то объединения позволяют описанные в них поля накладывать друг на друга в памяти машины.

Правила записи оператора объединения те же, что для оператора структуры. Например:

fbit    struc

b_1   db     0

b_2   db     0

b_3   db     0

b_4   db     0

fbit    ends

dblword     union

bits   fbit    {b_1=10h}

dwrd dd     ?

dblword     ends

Описание объединения dblword позволяет адресовать выделенную под переменную этого типа память целиком как двойное слово и по частям, как отдельные байты.

8.7. Списки

Одним из наиболее распространенных способов использования структур является динамическое формирование списков.

Списком называется последовательность элементов, каждый из которых может располагаться в произвольном месте памяти, и поэтому в состав элемента обязательно входит специальное поле связи, в котором хранится ссылка на следующий элемент списка. Последний элемент списка хранит в поле связи пустую ссылку, называемую nil. Ссылка на первый элемент списка должна храниться в некоторой переменной, которую называют указателем на вершину списка.

Как правило, элемент списка имеет следующий вид:

filds  struc

fild1  dw    ?

fild2  dw    ?

filds  ends

aitem struc

list     filds  <>               ; Поля данных

next  dw    ?                 ; Поле ссылки на следующий элемент

aitem ends

Следующая программа иллюстрирует работу «диспетчера» кучи. При обращении к макрокоманде new диспетчер, используя массив Status, находит подходящее место для размещения переменной указанного размера, отмечает выделяемое место как занятое и возвращает его адрес. В случае невозможности выделить требуемый ресурс возвращается адрес -1. Макрокоманда Delite изменяет статус заданного количества байт области памяти, начиная с указанного адреса, с «занято» на «свободно».

В программе сначала создается список из трех элементов. А затем, второй элемент удаляется из списка. Заканчивается программа перебором элементов списка и печатью их текстовых полей.

.model small

.386

nil = -1

Heap_size = 64*1024

filds  struc

fild1  db     8 dup(?)

fild2  db     ?

filds  ends

aitem struc

list     filds  <>

next  dw    ?

aitem ends

.data

Status        db     Heap_size/8 dup(0)

top    dw    ?

str1   db     'String 1'