Структуры


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

meddata struc ;Структура с именем meddata


index dd 0 ; Номер карты


sex db 0 ;Пол


birth dw 0 ;Год рождения


datein db ' / / ' ;Дата поступления


dateout db ' / / ' ;Дата выписки


meddata ends ;Конец описания структуры

Описание структуры можно располагать в любом месте программы, но до описания конкретных структурных переменных. Транслятор, встретившись с описанием структуры, не транслирует ее текст, т.е. не выделяет место в памяти, а просто запоминает приведенное описание, чтобы воспользоваться им в дальнейшем, если в программе встретятся объявления переменных типа этой структуры.
В сегменте данных можно объявить любое количество переменных, соответствующих по составу описанной ранее структуре, дав им произвольные имена. Эти переменные можно заполнить при их объявлении конкретными данными (разумеется, соответствующими элементам описанной ранее структуры), но можно и не указывать конкретных данных, если данную переменную предполагается инициализировать не на этапе ее объявления, а по ходу выполнения программы. В последнем случае транслятор выделяет под переменную место в памяти (в нашем примере 23 байт), заполнив ее той конкретной информацией, которая была указана в описании структуры:

data segment


pat 1 meddata <1234567, 'м',1955, 1З/06/981, '15/06/98'>


pat2 meddata <1982234, 'м',1932, '18/06/98', '25/06/98 '>


pat3 meddata <4389012, 'ж',1966, '01/12/97', '15/12/97'>


pattemp meddata <>


data ends

Имена patl, pat2 и т.д. будут служить именами переменных, каждая из которых содержит полный комплект данных об одном пациенте. Угловые скобки ограничивают конкретные данные, поступающие в каждую структурную переменную. Для переменной с именем pattemp транслятор выделит в памяти 23 байт, поместив в нее в точности то, что было указано в описании структуры (нули и два символьные шаблона для даты):

0,0,0, ' / / ',' / / '

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

mov EAX,patl.index ;ЕАХ=1234567


mov SI,offset patl.datein ;31=смещение элемента patl.datein


mov DL,pat3.sex ;DL='ж'

Особенности использования в приложениях DOS 32-разрядных регистров (ЕАХ в первой строке приведенного фрагмента) будут описаны в гл. 4.
Адрес конкретной структурной переменной можно поместить в базовый или индексный регистр, и пользоваться им в конструкциях с косвенной адресацией:

mov BX,offset pat3 ;ВХ=смещение pat3


mov EAX,[BX].index ;EAX=4389012


mov [BX].sех='м' ;Программная инициализация


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

mov BX, off set pat2 ;ВХ=смещение pat2


add BX,sex ;ВХ=смещение pat2.sex


mov DL, [BX] ;DL='M'


mov SI,birth ;SI=5 (сомнительная команда)

Записи


Записи, как и структуры, представляют собой шаблоны, накладываемые на реальные данные с целью введения удобных мнемонических обозначений отдельных элементов данных. В отличие от структур, дающих имена байтам, словам, двойным словам или целым массивам, в записях определяются строки битов внутри байтов, слов или двойных слов.
Известно, что дата создания файла хранится в каталоге диска в виде 16-битового слова, в котором старшие 7 бит обозначают год (от 1980), следующие 4 бит - месяц и последние 5 бит - день (рис. 2.14).

Рис. 2.14. Формат записи даты в каталоге диска.

Эти данные удобно специфицировать с помощью записи filedate, определяемой в программе следующим образом:

fdate record year:7, month: 4, day:5

Ключевое слово record говорит о том, что имя fdate относится к записи, а мнемонические обозначения year, month и day являются произвольными именами отдельных битовых полей описываемого слона.
Включение в программу описания шаблона битовых полей позволяет отказаться от утомительного и чреватого ошибками определения "вручную" содержимого полного данного по задаваемым значениям его отдельных составляющих. Для приведенной выше записи объявления конкретных переменных будут выглядеть следующим образом:

filel fdate <5,6,7> ;7 июня 1985г.


file2 fdate <18,12,30> ;30 декабря 1998г.


file3 fdate <> ;"Пустая" (пока) переменная

Переменная filel будет определена, как число 0AC7h, file2 - как число 259Eh, а fileЗ - как число 0000h. При необходимости программного заполнения переменной типа fdate можно пользоваться именами ее составляющих, которые трактуются ассемблером, как индексы соответствующих битовых полей, отсчитываемые от младшего конца слова. Для приведенного примера day=0, month=5, a year=9. Однако в системе команд МП 86 практически нет средств работы с битовыми полями. Поэтому программное заполнение придется осуществлять с помощью команд сдвигов и логического сложения:

mov flle3,30 ;Помещаем день


mov AX,12 ;Месяц пока в АХ


mov CL,month ;Будем сдвигать на month бит


shl AX,CL ; Сдвинули месяц в АХ на 5 бит


or file3,AX ;Добавили биты месяца в file3


mov AX, 18 ;Год пока в АХ


mov CL,month ;Будем сдвигать на year бит


shl AX,CL ;Сдвинули год в АХ на 9 бит


or file3,AX ;Добавили биты года в file3

В итоге в переменной file3 окажется тот же код 259Eh, что и в переменной file2.