assembler. Учебник для вузов_Юров В.И_2003 -637с (862834), страница 63
Текст из файла (страница 63)
Описать структуру в программе можно только один раз,а определить — любое количество раз. После того как структура определена,то есть ее имя связано с именем переменной, возможно обращение к полямструктуры по их именам.Структуры281Описание шаблона структурыОписание шаблона структуры имеет следующий синтаксис:имя_структуры STRUC<описание полей>имя_структуры ENDSЗдесь <описание полей> представляет собой последовательность директив описания данных DB, DW, DD, DQ и DT. Их операнды определяют размер полей и принеобходимости — начальные значения. Этими значениями будут, возможно, инициализироваться соответствующие поля при определении структуры.Как мы уже отметили, при описании шаблона память не выделяется, так какэто всего лишь информация для транслятора. Местоположение шаблона в программе может быть произвольным, но, следуя логике работы однопроходного транслятора, шаблон должен быть описан раньше, чем определяется переменная с типом данных структуры.
То есть при описании в сегменте данных переменнойс типом некоторой структуры ее шаблон необходимо описать в начале сегментаданных либо перед ним.Рассмотрим работу со структурами на примере моделирования базы данныхо сотрудниках некоторого отдела. Для простоты, чтобы уйти от проблем преобразования информации при вводе, условимся, что все поля символьные. Определимструктуру записи этой базы данных следующим шаблоном:worker struc;информация о сотрудникеnamdb 30 dup (" ");фамилия, имя, отчествоsexdb " ";полpositiondb 30 dup (" ")должностьagedb 2 dup (" ");возрастstandingdb 2 dup (" ");стажsalarydb 4 dup (" ");оклад в рубляхbirthdate db 8 dup (" ");дата рожденияworker endsОпределение данных с типом структурыДля использования описанной с помощью шаблона структуры в программе необходимо определить переменную с типом данных структуры.
Для этого используется следующая синтаксическая конструкция:[имя переменной] имя_структуры <[список з н а ч е н и й ] >Здесь:Ж имя переменной — идентификатор переменной данного структурного типа. Задание имени переменной необязательно. Если его не указать, будет просто выделена область памяти размером в сумму длин всех элементов структуры;il список з н а ч е н и й — заключенный в угловые скобки список начальных значенийэлементов структуры, разделенных запятыми.
Его задание также необязательно. Если список указан не полностью, то все поля структуры для данной переменной инициализируются значениями из шаблона, если таковые заданы. Допускается инициализация отдельных полей, но в этом случае пропущенныеполя, которые будут инициализированы значениями из шаблона структуры,должны отделяться запятыми. Если при определении новой переменной с ти-282Глава 13. Сложные структуры данныхпом данных структуры мы согласны со всеми значениями полей в ее шаблоне(то есть заданными по умолчанию), то нужно просто написать угловые скобки. К примеру,victor worker < > .Для примера определим несколько переменных с типом описанной ранее структуры:datasegmentsotrlworker <"Гурко АндрейВячеславович",,'художник',1'33' , '15' , '1800' , '26.01.64 >sotr2 worker <"Михайлова1 Наталья Геннадьевна",'ж','программист'.'30','10'.'1680'.'27.10.58 >sotr3 worker <"Степанов Юрий Лонгинович",,'художник','38' , '20','1750','01.01.58'>sotr4worker <"ЮроваЕлена Александровна",'ж','связист',1'32' , '2' , , '09.01.66 >sotrS worker <> ;здесь все значения по умолчаниюdataendsМетоды работы со структурамиСмысл введения структурного типа данных в любой язык программирования состоит в объединении разнотипных переменных в один объект.
В языке должныбыть средства доступа к этим переменным внутри конкретного экземпляра структуры. Для того чтобы сослаться в команде на поле некоторой структуры, используется специальный оператор. (точка):адресное_выражение.имя_поля_структурыЗдесь:я адресное_выражение — идентификатор переменной некоторого структурноготипа или выражение в скобках в соответствии с указанными ранее синтаксическими правилами (рис. 13.1);* имя_поля_структуры — имя поля из шаблона структуры (это на самом деле тожеадрес, а точнее, смещение поля от начала структуры).Таким образом, оператор.
(точка) вычисляет выражение (адресное_выражение) ++ (имя_поля_структуры).[J—|Имя регистра f-j-rГ\]_КонстантаИмя переменной [Константа \JРис. 13.1. Синтаксис адресного выражения в операторе обращения к полю структурыПродемонстрируем с помощью определенной нами структуры worker некоторые приемы работы со структурами. К примеру, требуется извлечь в регистр АХзначения поля с возрастом. Так как вряд ли возраст трудоспособного человекаможет быть больше 99 лет, то после помещения содержимого этого символьногополя в регистр АХ его будет удобно преобразовать в двоичное представление командой AAD (см. главу 8). Будьте внимательны, так как из-за принципа храненияданных «младший байт по младшему адресу» старшая цифра возраста будет поме-Структуры283щена в AL, а младшая — в АН.
Для корректировки достаточно использовать команду xchg al.ah:mov a x , w o r d ptr sotrl.agexchg ah.al;a можно и так:lea b x , s o t r lmov ax,word ptr [bx].agexchg a h . a l;в al возраст sotrlДавайте представим, что сотрудников не четверо, а намного больше, и к томуже их число и информация о них постоянно меняются.
В этом случае теряетсясмысл явного определения переменных с типом worker для конкретных личностей.Ассемблер разрешает определять не только отдельную переменную с типом структуры, но и массив структур. К примеру, определим массив из 10 структур типаworker:mas_sotrworker 10 dup (<>)Дальнейшая работа с массивом структур производится так же, как и с одномерным массивом. Здесь возникает несколько вопросов. Как быть с размером и какорганизовать индексацию элементов массива?Аналогично другим идентификаторам, определенным в программе, трансляторназначает имени типа структуры и имени переменной с типом структуры атрибуттипа.
Значением этого атрибута является размер в байтах, занимаемый полямиструктуры. Извлечь это значение можно с помощью оператора TYPE. После тогокак становится известным размер экземпляра структуры, организация индексации в массиве структур не представляет особой сложности.
К примеру,worker strucworkerendsmas_sotrworker10 dup (<>)mov bx.type worker ;bx=77lea di,mas_sotr;извлечь и вывести на экран пол всех сотрудников:mov cx,10cycl:mov dl,[di].sex... ;вывод на экран содержимого;поля sex структуры workeradd di.bx;к следующей структуре в массиве mas_sortloop cyclКак выполнить копирование поля из одной структуры в соответствующее поледругой структуры? Или как выполнить копирование всей структуры? К примеру,выполним копирование поля пат третьего сотрудника в поле пат пятого сотрудника:worker strucworkermas_sotrendsworker10 dup (<>)mov bx,offset mas_sotrmov si,(type worker)*2add si,bx;si=77*2284Глава 13. Сложные структуры данныхmov d i , ( t y p e worker)*4add di,bxmov ex,30rep movsb;si=77*4Среди прилагаемых к книге файлов в каталоге ..\lessonl3\struct\ приведенапрограмма обслуживания базы данных о сотрудниках1.
На ее примере вы можетеглубже познакомиться с тем, как организовать работу со структурами в своей программе. Возможно, для читателя имеет смысл в полном объеме исследовать этупрограмму только после знакомства с макрокомандами в следующей главе.Ремесло программиста рано или поздно делает человека похожим на хорошуюдомохозяйку. Он, подобно ей, постоянно находится в поиске: где бы чего-нибудьсэкономить, урезать, из минимума продуктов сделать прекрасный обед. И если этоудается, то и моральное удовлетворение получается ничуть не меньше, а может,и больше, чем от прекрасного обеда у домохозяйки. Степень этого удовлетворения, как мне кажется, зависит от степени любви к своей профессии. С другой стороны, успехи в разработке программного и аппаратного обеспечения несколькорасслабляют программиста, и довольно часто наблюдается ситуация, когда длярешения некоторой мелкой задачи привлекаются тяжеловесные средства, эффективность которых в общем случае значима только при реализации сравнительнобольших проектов.В следующих двух разделах описаны два типа данных, наличие которых в языке помогает более эффективно распоряжаться памятью, выделенной программе.ОбъединенияПредставим ситуацию, когда мы используем некоторую область памяти для размещения того или иного объекта программы (переменной, массива или структуры).
Вдруг после некоторого этапа работы у нас отпадает надобность в этих данных. В обычном случае память остается занятой до конца работы программы.Конечно, ее можно было бы задействовать для хранения других переменных, нобез принятия специальных мер нельзя изменить тип и имя данных/Неплохо былобы иметь возможность переопределить эту область памяти для объекта с другимитипом и именем. Ассемблер предоставляет такую возможность в виде специального типа данных, называемого объединением. Объединение — тип данных, позволяющий трактовать одну и ту же область памяти как данные, имеющие разные типыи имена.Описание объединений в программе напоминает описание структур, то естьсначала указывается шаблон, в котором с помощью директив описания данныхперечисляются имена и типы полей:имя_объединения UNION<описание полей>имя_объединения ENDSОтличие объединений от структур состоит, в частности, в том, что при определении переменной типа объединения память выделяется в соответствии с размеВсе прилагаемые к книге файлы можно найти по адресу http://www.piter.com/download.
—Примеч. ред.Объединения285ром максимального элемента. Обращение к элементам объединения происходитпо их именам, но при этом нужно, конечно, помнить, что все поля в объединениинакладываются друг на друга. Одновременная работа с элементами объединенияисключена. В качестве элементов объединения можно использовать и структуры.Листинг 13.6, который мы сейчас рассмотрим, примечателен тем, что кроме демонстрации собственно типа данных объединение, в нем показывается возможность взаимного вложения структур и объединений.