Будь умным!


У вас вопросы?
У нас ответы:) SamZan.ru

Стуктуры Рассмотренные нами массивы представляют собой совокупность однотипных элементов

Работа добавлена на сайт samzan.ru: 2015-07-10

Данные сложного типа. Стуктуры.

Рассмотренные нами массивы представляют собой совокупность однотипных элементов. Но часто в приложениях возникает необходимость рассматривать некоторую совокупность данных разного типа как некоторый единый тип.

Это очень актуально, например, для программ баз данных, где необходимо связывать совокупность данных разного типа с одним объектом. Особенно если база данных пишется на ассемблере :)

По определению структура — это тип данных, состоящий из фиксированного числа элементов разного типа.

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

Задать шаблон структуры.

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

Определить экземпляр структуры.

Этот этап подразумевает инициализацию конкретной переменной заранее определенной (с помощью шаблона) структурой.

Организовать обращение к элементам структуры.

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

Описать структуру в программе означает лишь указать ее схему или шаблон; память при этом не выделяется. Этот шаблон можно рассматривать лишь как информацию для транслятора о расположении полей и их значении по умолчанию.

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

Описать структуру в программе можно только один раз, а определить — любое количество раз.

Описание шаблона структуры

Описание шаблона структуры имеет следующий синтаксис:

имя_структуры STRUC

<описание полей>

имя_структуры ENDS

Здесь <описание полей> представляет собой последовательность директив описания данных db, dw, dd, dq и dt.

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

Как мы уже отметили при описании шаблона, память не выделяется, так как это всего лишь информация для транслятора.

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

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

;описали шаблон стуктуры

worker struc ;информация о сотруднике

nam db 30 dup (' ') ;фамилия, имя, отчество

sex db 'м';пол, по умолчанию 'м' - мужской

position db 30 dup (' ') ;должность

age db 2 dup(' ') ;возраст

standing db 2 dup(' ') ;стаж

salary db 4 dup(' ') ;оклад

birthdate db 8 dup(' ') ;дата рождения

worker ends

Определение данных с типом структуры

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

[имя переменной] имя_структуры <[список значений]>

Здесь:

имя переменной — идентификатор переменной данного структурного типа.

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

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

Его задание также необязательно.

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

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

К примеру: victor worker <>.

Для примера определим несколько переменных с типом описанной выше структуры.

sotr1 worker <'Гурко Андрей Вячеславович',,'художник','33','15','1800','26.01.64'>

sotr2 worker <'Михайлова Наталья Геннадьевна','ж','программист','30','10','1680','27.10.58'>

sotr3 worker <'Степанов Юрий Лонгинович',,'художник','38','20','1750','01.01.58'>

sotr4 worker <'Юрова Елена Александровна','ж','свяэист','32','2',,'09.01.66'>

sotr5 worker <> ;здесь все значения по умолчанию

Методы работы со структурой

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

В языке должны быть средства доступа к этим переменным внутри конкретного экземпляра структуры. Для того чтобы сослаться в команде на поле некоторой структуры, используется специальный оператор — символ "." (точка). Он используется в следующей синтаксической конструкции:

адресное_выражение.имя_поля_структуры

Здесь:

адресное_выражение — идентификатор переменной некоторого структурного типа или выражение в скобках указывающее на ее адрес

имя_поля_структуры — имя поля из шаблона структуры. Это, на самом деле, тоже адрес, а точнее, смещение поля от начала структуры.

Теперь примерчик...

Эта программа уже выводит на экран информацию о первом сотруднике. Запускаем, анализируем, просветляемся...

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

Язык ассемблера разрешает определять не только отдельную переменную с типом структуры, но и массив структур.

К примеру, определим массив из 10 структур типа worker:

mas_sotr worker 10 dup (<>)

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

Как быть с размером и как организовать индексацию элементов массива?

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

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

К примеру, программа выводит на экран содержимое поля sex всех структур worker в массиве mas_sotr:

Данные сложного типа. Объединения.

Представим ситуацию, когда мы используем некоторую область памяти для размещения некоторого объекта программы (переменной, массива или структуры). Вдруг после некоторого этапа работы у нас отпала надобность в использовании этих данных. Обычно память останется занятой до конца работы программы. Конечно, в принципе, ее можно было бы использовать для хранения других переменных, но при этом без принятия специальных мер нельзя изменить тип и имя. Неплохо было бы иметь возможность переопределить эту область памяти для объекта с другим типом и именем. Язык ассемблера предоставляет такую возможность в виде специального типа данных, называемого объединением.

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

Описание объединений в программе напоминает описание структур, то есть сначала описывается шаблон, в котором с помощью директив описания данных перечисляются имена и типы полей:

имя_объединения UNION

<описание полей>

имя_объединения ENDS

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

Обращение к элементам объединения происходит по их именам, но при этом нужно, конечно, помнить о том, что все поля в объединении накладываются друг на друга.

Одновременная работа с элементами объединения исключена. В качестве элементов объединения можно использовать и структуры.

Данные сложного типа. Записи.

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

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

Суммарный размер записи определяется суммой размеров ее полей и не может быть более 8, 16 или 32 бит.

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

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

Использование записей в программе, так же, как и структур, организуется в три этапа:

Задание шаблона записи, то есть определение набора битовых полей, их длин и, при необходимости, инициализация полей.

Определение экземпляра записи. Так же, как и для структур, этот этап подразумевает инициализацию конкретной переменной типом заранее определенной с помощью шаблона записи.

Организация обращения к элементам записи.

Компилятор TASM, кроме стандартных средств обработки записей, поддерживает также и некоторые дополнительные возможности их обработки.

Описание записи

Описание шаблона записи имеет следующий синтаксис:

имя_записи RECORD <описание элементов>

Здесь:

<описание элементов> представляет собой последовательность описаний отдельных элементов записи согласно синтаксической диаграмме (см. рис.):

При описании шаблона память не выделяется, так как это всего лишь информация для транслятора ассемблера о структуре записи.

Пример:

iotest record i1:1,i2:2=11,i3:1,i4:2=11,i5:2=00

Так же, как и для структур, местоположение шаблона в программе может быть любым, но при этом необходимо учитывать логику работы однопроходного транслятора.

Определение экземпляра записи

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

Анализируя эту синтаксическую диаграмму, можно сделать вывод, что инициализация элементов записи осуществляется достаточно гибко. Рассмотрим несколько вариантов инициализации.

Если инициализировать поля не требуется, то достаточно указать ? при определении экземпляра записи:

flag iotest ?

Если вы составите и исследуете в отладчике тестовый пример с данным определением записи, то увидите, что все поля переменной типа запись flag обнуляются. Это происходит несмотря на то, что в определении записи заданы начальные значения полей.

Если требуется частичная инициализация элементов, то они заключаются в угловые (< и >) или фигурные ({ и }) скобки.

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

К примеру, согласиться со значениями по умолчанию можно так:

flag iotest <> ;согласились со значением по умолчанию

Изменить значение поля i2 можно так:

flag iotest <,10,> ; переопределили i2

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

flag iotest {i2=10} ;переопределили i2,

;не обращая внимания на порядок

;следования других компонентов записи

Работа с записями

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

Прежде всего для понимания проблемы нужно усвоить несколько моментов:

Каждому имени элемента записи ассемблер присваивает числовое значение, равное количеству сдвигов вправо, которые нужно произвести для того, чтобы этот элемент оказался “прижатым” к началу ячейки. Это дает нам возможность локализовать его и работать с ним. Но для этого нужно знать длину элемента в битах.

mov ah,i2 ;получаем количество сдвигов в право

Сдвиг вправо производится с помощью команды сдвига shr.

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

width имя_элемента_записи ;значением оператора

;будет размер элемента в битах

width имя_экземпляра_записи

или

 width имя_типа_записи ;значением оператора

;будет размер всей записи в битах.

 mov al,width i2

...

mov ax,width iotest

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

Сами действия по преобразованию элементов записи производятся с помощью логических команд.

И так, поскольку в системе команд МП 86 практически нет средств работы с битовыми полями, поэтому непосредственно обратиться к элементу записи невозможно. Чтобы произвести обработку интересующего нас элемента, его нужно сначала выделить, сдвинуть, при необходимости, к младшим разрядам, выполнить необходимые действия и поместить его обратно на свое место в записи. Это приходится осуществлять с помощью команд сдвигов и логических операций - and, or, xor и not.

Выделение элемента записи:

Поместить запись во временную память — регистр (8, 16 или 32-битный в зависимости от размера записи).

Получить битовую маску, соответствующую элементу записи, с помощью оператора mask.

Локализовать биты в регистре с помощью маски и команды and.

Сдвинуть биты элемента к младшим разрядам регистра командой shr. Число разрядов для сдвига получить с использованием имени элемента записи.

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

Работа с элементом записи:

Как мы уже выяснили, с элементами записи производятся любые действия, как над обычной двоичной информацией.

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

Помещение измененного элемента на его место в запись:

Используя имя элемента записи в качестве счетчика сдвигов, сдвинуть влево биты элемента записи (команда shl).

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

Подготовить исходную запись к вставке измененного элемента путем обнуления битов в записи на месте этого элемента. Это можно сделать путем наложения командой and инвертированной маски элемента записи на исходную запись.

С помощью команды or наложить значение в регистре на исходную запись.

Ну и примерчик для медитации...

Програмулина ни чего не выводит на экран, так как предназначена для медитации на нее под отладчиком. В программе создается экземпляр записи iotest с именем flag, имеющий двоичное значение (по умолчанию) - 10001100 (8Сh). Программа устанавливает третий слева бит (младший бит i2) в единичку. Соответственно, после этих изменений, в переменной flag должно быть значение ACh (10101100).

Теперь листинг программы...

И немного отладчика...

Этот скрин сделан после выполнения первых двух команд программы. Следующий уже после выполнения команды or.


1. КИЇВСЬКИЙ НАЦІОНАЛЬНИЙ ЕКОНОМІЧНИЙ УНІВЕРСИТЕТ імені ВАДИМА ГЕТЬМАНА Кафедра менеджменту
2. Курсовая работа- Обратная сила уголовного закона
3. Права о которых военнослужащие и военные пенсионеры не знают
4.  Маркетинговая среда фирмы ~ это совокупность активных субъектов и сил действующих за пределами фирмы и вли
5. Если хочешь чтото получить сумей чтото отдать
6. Основные понятия, термины и определения в безопасности жизнедеятельности
7. тематической статистики
8. Fshioned ~ long used CM ~ dispprovl PM Timetested ~ long used CM ~ pprovl CM Primry nd secondry menings Exest in one word
9. темами нелинейных уравнений СНУ называются системы вида- 3
10. Творческий характер произведения как признак объекта авторского права
11. тематике за 1 класс
12. тема нормативного регулирования бухгалтерского учета и отчетности в России
13. Валютная система мира в межвоенный период
14. Введение Создание персонального компьютера можно отнести к одному из самых значительных изобретений 20 век
15. реферат дисертації на здобуття наукового ступеня кандидата економічних наук.9
16.  Ходьба медленная
17. Вкажіть розважку порошків за прописом- Rp
18. Методология управление проектами Цель работы- Выявить проблемы управления программными проектами
19. Проект автоматической линии для обработки детали типа Вал-шестерня
20. Благо это предмет явление процесс продукт труда удовлетворяющий определенную человеческую потре