Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:

Микропроцессоры

.pdf
Скачиваний:
91
Добавлен:
21.05.2015
Размер:
5.46 Mб
Скачать

Далее программисту нужно выдать обычную команду деления div для выполнения деления содержимого ах на одну BCD-цифру, находящуюся в байтовом регистре или байтовой ячейке памяти.

Аналогично ааш, команде aad можно найти и другое применение – использовать ее для перевода неупакованных BCD-чисел из диапазона 0... 99 в их двоичный эквивалент.

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

35. ПРОЦЕДУРЫ. ОСНОВНЫЕ ПОНЯТИЯ

Для описания последовательности команд в виде процедуры в языке ассембле-ра используются две директивы: PROC и ENDP.

В заголовке процедуры (директиве PROC) обязательным является только задание имени процедуры. Среди большого количества операн-дов директивы PROC следует особо выделить [расстояние]. Этот атрибут может при-нимать значения NEAR или FAR и характеризует возможность обращения к проце-дуре из другого сегмента кода. По умолчанию атрибут [расстояние] принимает значение NEAR.

Процедура может размещаться в любом месте программы, но так, чтобы на нее случайным образом не попало управление. Если процедуру просто вставить в об-щий поток команд, то процессор воспримет команды процедуры как часть этогоимя_процедуры PROC [[модификатор_языка ] язык] [расстояние ]

[ARG СПИСОК апгл/чвитпи 1 ЗЭГОЛОВОК процедуры

[RETURN список_элементов] команды, директивы ассемблера

Учитывая это обстоя-тельство, есть следующие варианты размещения процедуры в программе:

впрограммы (до первой исполняемой команды);

вконце программы (после команды, возвращающей управление операционной системе);

промежуточный вариант — внутри другой процедуры или основной програм-мы (в этом случае необходимо предусмотреть обход процедуры с помощью ко-манды безусловного перехода ОМ Р);

в другом модуле (библиотеке DLL).

Размещение процедуры в начале сегмента кода предполагает, что последова-тельность команд, ограниченная парой директив PROC и ENDP, будет размещена до метки, обозначающей первую команду, с которой начинается выполнение програм-мы. Эта метка должна быть указана как параметр директивы END, обозначающей конец программы:

36. ОРГАНИЗАЦИЯ ПРОЦЕДУР. ПЕРЕДАЧА ПАРАМЕТРОВ В ПРОЦЕДУРУ

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

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

Константы — данные, значения которых не могут изменяться.

Сигнатура процедуры (функции) — это имя функции, тип возвращаемого значения и список аргументов с указанием порядка их следования и типов.

Семантика процедуры (функции) — это описание того, что данная функция делает. Семантика функции включает в себя описание того, что является результатом вычисления функции, как и от чего этот результат зависит. Обычно результат выполнения зависит только от значений аргументов функции, но в некоторых модулях есть понятие состояния. Тогда результат функции может зависеть от этого состояния, и, кроме того, результатом может стать изменение состояния. Логика этих зависимостей и изменений относится к семантике функции. Полным описанием семантики функций является исполняемый код функции или математическое определение функции.

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

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

через регистры; через общую область памяти; через стек;

с помощью директив extern и public.

Передача аргументов через регистры – это наиболее простой в реализации способ передачи данных. Данные, переданные подобным способом, становятся доступными немедленно после передачи управления процедуре. Этот способ очень популярен при небольшом объеме передаваемых данных.

Ограничения на способ передачи аргументов через регистры:

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

ограничение размера передаваемых данных размерами регистра. Если размер данных превышает 8, 16 или 32 бита, то передачу данных посредством регистров произвести нельзя. В этом случае передавать нужно не сами данные, а указатели на них.

Передача аргументов через общую область памяти – предполагает, что вызывающая и вызываемая программы используют некоторую область памяти как общую. Для организации такой области памяти используется атрибут комбинирования сегментов common. Наличие этого атрибута указывает компоновщику, как нужно комбинировать сегменты, имеющие одно имя: все сегменты, имеющие одинаковое имя в объединяемых модулях, будут располагаться компоновщиком, начиная с одного адреса оперативной памяти. Это значит, что они будут перекрываться в памяти и, следовательно, совместно использовать выделенную память. Данные в сегментах common могут иметь одинаковые имена. Главное – структура общих сегментов. Она должна быть идентична во всех модулях использующих обмен данными через общую память.

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

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

Стек обслуживается тремя регистрами:

ESS - указатель дна стека (начала сегмента стека); ESP - указатель вершины стека;

EBP - указатель базы.

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

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

push ebp

mov ebp, esp

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

Конец процедуры также должен содержать действия, обеспечивающие корректный возврат из процедуры. Фрагмент кода, выполняющего такие действия, имеет свое название — эпилог процедуры. Код эпилога должен восстановить контекст программы в точке вызова процедуры из вызывающей программы. При этом, в частности, нужно откорректировать содержимое стека, убрав из него ставшие ненужными аргументы, передававшиеся в процедуру. Это можно сделать несколькими способами:

используя последовательность из n команд pop xx. Лучше всего это делать в вызывающей программе сразу после возврата управления из процедуры;

откорректировать регистр указателя стека esp на величину 4*n, например, командой

add esp,NN

где NN=4*n (n — количество аргументов). Это также лучше делать после возврата управления вызывающей процедуре;

используя машинную команду ret n в качестве последней исполняемой команды в процедуре, где n — количество байт, на которое нужно увеличить содержимое регистра esp после того, как со стека будут сняты составляющие адреса возврата. Этот способ аналогичен предыдущему, но выполняется автоматически микропроцессором.

Для доступа к аргументу 4 достаточно сместиться от содержимого ebр на 8 байт (4 байта хранят адрес возврата в вызывающую процедуру, и еще 4 байта хранят значение регистра ebр, помещенное в стек данной процедурой), для аргумента 3 — на 12 и т. д.

Пролог и эпилог прогцедуры можно также заменить командами поддержки языков высокого уровня: Команда enter подготавливает стек для обращения к аргументов, имеет 2 операнда :

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

Команда leave подготавливает стек к возврату из процедуры, не имеет операндов. Передача аргументов с помощью директив extern и public используется в случаях, если оба модуля используют сегмент данных вызывающей программы; у каждого модуля есть свой собственный сегмент данных;

модули используют атрибут комбинирования сегментов public в директиве сегментации segment.

37.КОНЦЕПЦИЯ ПРЕРЫВАНИЙ. КЛАССИФИКАЦИЯ ПРЕРЫВАНИЙ.

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

прерываний. К аппаратным средствам относятся:

1.Выводы микропроцессора:

a.INTR – вывод для входного сигнала внешнего прерывания. На этот вход поступает выходной сигнал от микросхемы контроллера прерываний 8259А.

b.INTA – вывод микропроцессора для выходного сигнала подтверждения получения сигнала прерывания микропроцессором. Этот выходной сигнал поступает на одноименный вход INTA микросхемы контроллера прерываний 8259А.

c.NMI – вывод микропроцессора для входного сигнала немаскируемого прерывания.

2.Микросхема программируемого контроллера прерываний 8259А. Она предназначена для фиксирования сигналов прерываний от восьми различных внешних устройств.

3.Внешние устройства: клавиатура, таймер, диски и т.д.

К программным средствам системы прерываний реального режима относятся:

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

2.Следующие флаги в регистре флагов flags\eflags (слайд 4):

a.IF (Interrupt Flag) – флаг прерывания. Предназначен для маскирования (запрещения) аппаратных прерываний, то есть прерываний по входу INTR. На обработку прерываний остальных типов флаг IF влияния не оказывает. Если IF=1 микропроцессор обрабатывает внешние прерывания, если IF=0 микропроцессор игнорирует сигналы на входе INTR;

b.TF (Trace Flag) – флаг трассировки. Единичное состояние флага TF переводит микропроцессор в режим покомандной работы. В режиме покомандной работы после выполнения каждой машинной команды в микропроцессоре генерируется внутреннее прерывание с номером 1, и далее следуют действия в соответствии с алгоритмом обработки данного прерывания.

3.Машинные команды микропроцессора int, into, iret, cli, sti.

Функции выполняемые микросхемой контроллера прерываний:

-фиксирование запросов на обработку прерывания от восьми источников, формирование единого запроса на прерывание и подача его на вход INTR микропроцессора

-формирование номера вектора прерывания и выдача его на шину данных

-организация приоритетной обработки прерываний

-запрещение (маскирование) прерываний с определенными номерами.

38.ВНЕШНИЕ ПРЕРЫВАНИЯ.

Прерывания могут быть внешними и внутренними. Внешние прерывания вызываются внешними, по отношению к микропроцессору, событиями. У микропроцессора есть два физических контакта INTR и NMI (слайд 2). На них и формируются внешние по отношению к микропроцессору сигналы, возрастающие фронты которых извещают о том, что некоторое внешнее устройство инициирует прерывание. Вход INTR (Interrupt Request) предназначен для фиксации запросов от различных периферийных устройств. Вход NMI (Non Maskable Interrupt) – немаскируемое прерывание. Используется для того, чтобы сообщить микропроцессору о событии, требующем безотлагательной обработки или критической ошибке. Внешние прерывания относятся к непланируемым прерываниям.

39.. ВНУТРЕННИЕ ПРЕРЫВАНИЯ.

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

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

2.обработка машинной команды int xx (слайд 3). Этот тип прерываний называется программным. Это – планируемые прерывания, так как с их помощью программист обращается в нужное для него время за обслуживанием своих запросов либо к операционной системе, либо к BIOS, либо к собственным программам обработки прерываний.

40.ПРОГРАММНЫЕ ПРЕРЫВАНИЯ.

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

Процессоры семейства х86 и совместимые с ними могут порождать 256 прерываний. Адреса всех 256 функций обработки прерываний (так называемые векторы прерываний) хранятся в специальной таблице векторов прерываний.

Прерывания могут быть программными и аппаратными. (Про аппаратные можете не читать, но будет понятнее)

Аппаратные прерывания происходят по запросу периферийных устройств и называются IRQ (Interrupt Requests). Архитектура шины ISA ограничивает их число до 16 (IRQ0 — IRQ15).

К аппаратным прерываниям относятся также специальные прерывания, которые генерирует сам процессор. Такие прерывания используются для обработки «исключительных ситуаций» — неверный операнд, неизвестная команда, переполнение и другие непредвиденные операции, когда процессор сбит с толку и не знает, что делать. Эти прерывания имеют свои обозначения и никак не относятся к зарезервированным для периферии прерываниям IRQ0-IRQ15.

Все аппаратные прерывания можно разделить на две группы: прерывания, которые можно игнорировать («замаскировать») и те, которые игнорировать нельзя. Первые называются маскируемыми (maskable), а вторые — немаскируемыми (non-maskable). Аппаратные прерывания могут быть отключены путем установки флага IF регистра признаков в 0. Единственное прерывание, которое отключить нельзя — это NMI, немаскируемое прерывание, генерирующееся при сбое памяти, сбое в питании процессора и подобных форсмажорных обстоятельствах.

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

41.ОБРАБОТКА ПРЕРЫВАНИЙ В РЕАЛЬНОМ РЕЖИМЕ

В реальном режиме имеются программные и аппаратные прерывания. Программные прерывания инициируются командой INT, аппаратные - внешними событиями, асинхронными по отношению к выполняемой программе. Обычно аппаратные прерывания инициируются аппаратурой ввода/вывода после завершения выполнения текущей операции.

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

Для обработки прерываний в реальном режиме процессор использует таблицу векторов прерываний. Эта таблица располагается в самом начале оперативной памяти, т.е. её физический адрес - 00000.

Таблица векторов прерываний реального режима состоит из 256 элементов по 4 байта, таким образом её размер составляет 1 килобайт. Элементы таблицы - дальние указатели на процедуры обработки прерываний. Указатели состоят из 16-битового сегментного адреса процедуры обработки прерывания и 16-битового смещения. Причём смещение хранится по младшему адресу, а сегментный адрес - по старшему.

Когда происходит программное или аппаратное прерывание, текущее содержимое регистров CS, IP а также регистра флагов FLAGS записывается в стек программы (который, в свою очередь, адресуется регистровой парой SS:SP). Далее из таблицы векторов прерываний выбираются новые значения для CS и IP, при этом управление передаётся на процедуру обработки прерывания.

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

Завершив обработку прерывания, процедура должна выдать команду IRET, по которой из стека будут извлечены значения для CS, IP, FLAGS и загружены в соответствующие регистры. Далее выполнение прерванной программы будет продолжено.

Что же касается аппаратных маскируемых прерываний, то в компьютере IBM AT и совместимых с ним существует всего шестнадцать таких прерываний, обозначаемых IRQ0-IRQ15. В реальном режиме для обработки прерываний IRQ0-IRQ7 используются вектора прерываний от 08h до 0Fh, а для IRQ8-IRQ15 - от

70h до 77h.

42.ОБРАБОТКА ПРЕРЫВАНИЙ В ЗАЩИЩЕННОМ РЕЖИМЕ

В защищённом режиме все прерывания разделяются на два типа - обычные прерывания и исключения (exception - исключение, особый случай).

Обычное прерывание инициируется командой INT (программное прерывание) или внешним событием (аппаратное прерывание). Перед передачей управления процедуре обработки обычного прерывания флаг разрешения прерываний IF сбрасывается и прерывания запрещаются.

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

43. СЛОЖНЫЕ СТРУКТУРЫ ДАННЫХ. СПОСОБЫ ОРГАНИЗАЦИИ МАССИВОВ

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

последовательность байт, а цепочка это более общее название для случаев, элементы

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

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

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

При необходимости использовать массив в программе его нужно моделировать одним из следующих способов:

1. Перечислением элементов массива в поле операндов одной из директив описания данных. При перечислении элементы разделяются запятыми.(слайд

3)

2.Используя оператор повторения dup. На примере размер каждого элемента 2 байта. Такой способ определения используется для резервирования памяти с целью размещения и инициализации элементов массива.

3.Используя директивы label и rept. Директива rept относится к макросредствам языка ассемблера и вызывает повторение указанное число раз строк, заключенных между директивой и строкой endm. Достоинство директивы label в том что она не резервирует память, а лишь определяет характеристики объекта. Используя несколько директив label, написанных одна за другой можно присвоить одной и той же области памяти разные имена и типы.

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

Доступ к элементам массива.

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

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

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

Для работы с массивами предоставляются: базовые и индексные регистры, позволяющие реализовать несколько режимов адресации данных. Микропроцессор позволяет масштабировать индекс. Это означает, что если указать после имени индексного регистра знак умножения с последующей цифрой 2, 4 или 8, то содержимое индексного регистра будет умножаться на 2, 4 или 8. Применение масштабирования

облегчает работу с массивами, которые имеют размер элементов равный 2, 4 или 8 байтам, так как микропроцессор сам производит коррекцию индекса для получения адреса очередного элемента массива. Нужно лишь загрузить в индексный регистр значение требуемого индекса, считая от 0. Возможность масштабирования появилась в микропроцессорах intel начиная с i486

Двумерные массивы.

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

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

по строкам или по столбцам.

Если последовательность однотипных элементов в памяти трактуется как двумерный массив, расположенный по строкам, то адрес элемента (i,j) вычисляется по формуле (слайд 7).

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

44.ЦЕПОЧЕЧНЫЕ КОМАНДЫ.

Цепочечные команды:

 

 

 

 

 

Название

 

Команды

 

Действие

 

 

 

 

 

пересылка цепочки

 

movs <адр. приемника>,

 

копирует один элемент цепочки из

 

<адр. источника>

 

операнда источника в операнд приемник

 

 

movsb, movsw, mowsd

 

 

 

 

 

 

 

 

 

 

 

 

cmps <адр. приемника>,

 

сравнивает элементы цепочек из операнда

сравнение цепочек

 

<адр. источника>

 

 

 

источника и операнда приемника

 

 

cmpsb, cmpsw, cmpsd

 

 

 

 

 

 

 

 

 

 

 

 

scas <адр. приемника>

 

сканирует цепочку приёмник на

сканирование цепочки

 

 

присутствие некоторого элемента (задаётся

 

scasb, scasw, scasd

 

 

 

 

в регистре аккумуляторе)

 

 

 

 

 

 

 

 

 

загрузка элемента из

 

lods <адр. источника>

 

загрузить элемент из цепочки источника в

цепочки

 

lodsb, lodsw, lodsd

 

регистр аккумулятор

 

 

 

 

 

сохранение элемента в

 

stos <адр. приемника>

 

восстановить элемент из регистра

цепочке

 

stosb, stosw, stosd

 

аккумулятора в цепочку

 

 

 

 

 

получение элемента

 

ins <адр. приемника>,

 

загрузить элемент в цепочку приемник из

цепочки из порта

 

<номер порта>

 

 

 

указанного порта ввода/вывода

ввода/вывода

 

insb, insw, insd

 

 

 

 

 

 

 

 

 

вывод элементов цепочки

 

outs <номер порта>,

 

переслать элемент из цепочки источника в

 

<адр. источника>

 

в порт ввода/вывода

 

outbs, outws, outds

 

указанный порт ввода/вывода

 

 

 

 

 

 

 

 

 

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

повторения. Они предназначены для использования цепочечными командами. Префиксы имеют свои обозначения. Эти префиксы повторения указываются перед нужной цепочечной командой в поле метки. Цепочечная команда без префикса выполняется один раз. Размещение префикса перед цепочечной командой заставляет ее выполняться в цикле. Отличия префиксов в том, на каком основании принимается решение о циклическом выполнении цепочечной команды: либо по состоянию регистра ecx/cx, либо по флагу нуля zf.

Префикс повторения rep. Этот префикс используется с командами,

реализующими операции-примитивы пересылки и сохранения элементов цепочек – movs, stos. Префикс заставляет данные команды выполняться, пока содержимое в ecx/cx не станет равным 0. При этом цепочечная команда, перед которой стоит префикс, автоматически уменьшает содержимое ecx/cx на единицу. Та же команда, но без префикса этого не делает. Префиксы повторения repe или repz. Эти префиксы являются абсолютными синонимами. Они заставляют цепочечную команду выполняться до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен 1. Как только одно из условий нарушается управление передается следующей команде программы. Благодаря возможности анализа флага zf наиболее эффективно эти префиксы можно использовать с командами cmps и scas для поиска отличающихся элементов цепочек.

Префиксы повторения repne или repnz Эти префиксы также синонимы. Они заставляют цепочечную команду циклически выполняться до тех пор, пока содержимое

ecx/cx не равно нулю или флаг zf равен нулю. При невыполнении одного из этих условий работа команды прекращается. Данные команды также можно использовать с командами cmps и scas, но для поиска совпадающих элементов цепочек.

Цепочка_источник, адресуемая операндом адрес_источника может находиться в текущем сегменте данных, определяемом регистром ds. Цепочка_приемник, адресуемая операндом адрес_приемника, должна быть в дополнительном сегменте данных, адресуемом сегментным регистром es. Допускается замена только регистра ds. Регистр es подменять нельзя. Вторые части адресов – смещения цепочек – также находятся в строго определенных местах. Для цепочки_источника это esi/si (индексный регистр источника).

Для цепочки_получателя это регистр edi/di (индексный регистр приемника). На самом деле набор команд микропроцессора имеет соответствующие

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

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

1.От начала цепочки к концу, то есть в направлении возрастания адресов.

2.От конца цепочки к началу, то есть в направлении убывания адресов. Цепочечные команды сами выполняют модификацию регистров, адресующих

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

45.МАКРОСРЕДСТВА ЯЗЫКА АССЕМБЛЕРА.

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

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

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

Существует три варианта расположения макроопределения:

1.В начале исходного текста программы до сегмента кода и данных с тем, чтобы не ухудшать читабельность программы. Этот вариант применяется, когда определенные макрокоманды актуальны только в пределах одной программы.

2.В отдельном файле. Этот вариант подходит при работе над несколькими программами одной проблемной области. Чтобы сделать доступными эти макроопределения в конкретной программе, необходимо в начале исходного текста записать директиву include (слайд 3).

3.В макробиблиотеке. Если есть универсальные макрокоманды, то их целесообразно записать в макробиблиотеку. Сделать актуальными макрокоманды из макробиблиотеки можно с помощью все той же директивы include. Недостаток 2 и 3 способов в том, что в исходный текст программы включаются абсолютно все макроопределения. Для исправления ситуации можно использовать директиву (слайд 4) в качестве операндов которой через запятую перечисляются имена макрокоманд, которые не должны включаться в текст программы.

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

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

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

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

должно быть активизировано с помощью макрокоманды (слайд 5). Результатом применения в исходном тексте программы будет замещение

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

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

1. Строка может состоять из :

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

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

2. Для того, чтобы указать, что некоторый символ внутри строки, представляющей фактический параметр является собственно символом, а не чем-то иным применяется специальный оператор «!». Этот оператор ставится непосредственно перед описанным выше символом и его действие эквивалентно заключению данного символа в угловые скобки.

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

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

аргумент. Это может произойти в случае, когда он является частью некоторого идентификатора. Тогда последовательность символов формального аргумента отделяют от остального контекста с помощью специального символа «&». Если в программе некоторая макрокоманда вызывается несколько раз, то в процессе макрогенерации возникает ситуация, когда в программе один идентификатор будет определен несколько раз, что будет распознано транслятором как ошибка. Для выхода из подобной ситуации применяется директива local. Ее необходимо задавать непосредственно за заголовком макроопределения.

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

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

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

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

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

Директивы условной компиляции.

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

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

46. ДИРЕКТИВЫ КОМПИЛЯЦИИ ПО УСЛОВИЮ. ДИРЕКТИВЫ ГЕНЕРАЦИИ ОШИБОК

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

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

Всего имеется 10 типов условных директив компиляции. Их логично попарно объединить в четыре группы:

1.Директивы IF и IFE — условная трансляция по результату вычисления логического выражения.

2.Директивы IFDEF и IFNDEF — условная трансляция по факту определения символического имени.

3.Директивы IFB и IFNB — условная трансляция по факту определения фактического аргумента при

вызове макрокоманды.

4.Директивы IFIDN, IFIDNI, IFDIF и IFDIFI — условная трансляция по результату сравнения строк

символов.

5. Условные директивы компиляции имеют общий синтаксис и применяются в составе следующей синтаксической конструкции:

IFxxx

логическое_выражение_или_аргу

менты фрагмент_программы_1

ELSE

фрагмент_программы_2 ENDIF

6.Заключение некоторых фрагментов текста программы —

фрагмент_программы_1 и фрагмент_программы_2 — между директивамиIFxxx, ELSE и ENDIF приводит к их выборочному включению в объектный модуль. Какой именно из этих фрагментов — фрагмент_программы_1 илифрагмент_программы_2 — будет включен в объектный модуль, зависит от конкретного типа условной директивы, задаваемого значением xxx, и значения условия, определяемого операндом (операндами) условной директивылогическое_выражение_или_аргумент(ы).

Синтаксические конструкции, соответствующие директивам условной компиляции, могут быть вложенными друг в друга

Директивы IF и IFE

Синтаксис этих директив следующий:

IF(E) логическое_выражение фрагмент_программы_1

ELSE

фрагмент_программы_2 ENDIF

Обработка этих директив макроассемблером заключается в вычислениилогического_выражения и включении в объектный модульфрагмент_программы_1 или фрагмент_программы_2 в зависимости от того, в какой директиве IF или IFE это выражение встретилось:

если в директиве IF логическое выражение истинно, то в объектный модуль помещается фрагмент_программы_1.

Если логическое выражение ложно, то при наличии директивы ELSE в объектный код

помещается фрагмент_программы_2. Если же директивы ELSE нет, то вся часть программы между директивами IF иENDIF игнорируется и в объектный модуль ничего не включается. Кстати сказать, понятие истинности и ложности значениялогического_выражения весьма условно. Ложным оно будет считаться, если его значение равно нулю, а истинным — при любом значении, отличном от нуля.