Архитектура Аудит Военная наука Иностранные языки Медицина Металлургия Метрология
Образование Политология Производство Психология Стандартизация Технологии


Использование Макросов в Языке Ассемблера



Синтаксис

Определение макроса:

macro имя_макроса ( [параметр1 [, параметр2...]] )

последовательность_элементов

end имя_макроса;

Вызов макроса:

имя_макроса( [параметр1 [, параметр2...]] );

Объявление внешних макросов, импорт из макробиблиотек:

import [имя_макроса1 [, имя_макроса2...]] from

имя_библиотеки;

Описание

Здесь имя_макроса - произвольный идентификатор. Формальные параметры макроса (если макрос имеет параметры) также должны быть идентификаторами.

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

В качестве аргументов вызова макроса могут быть использованы:

· регистры,

· неопределённые идентификаторы,

· константные выражения.

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

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

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

macro entry_point( name )

< name>

nul 10;

call subroutine;

end entry_point;

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

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

Внутри тела макроса возможно использование блоков условной компиляции.

Запрещен явный и опосредованный рекурсивный вызов одного и того же макроса.

Использование Меток в Макросах

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

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

Например:

macro FEQ ( Res, Arg1, Arg2 )

extern FCmp: label;

own Cont: label;

ar5 = sp;

sp += 2;

[ ar5++ ] = Arg1;

[ ar5 ] = Arg2;

call FCmp;

if carry delayed skip Cont

with Res = false noflags;

sp -= 2;

// cond. skip Cont

if < > 0 skip Cont;

Res++;

< Cont>

end FEQ;

Макрос FEQ(), использующий собственную метку Cont для организации внутреннего ветвления, может инстанцироваться более одного раза.

Использование спецификатора own при объявлении метки, возможно, только внутри тела макросов.

Импорт Макросов из Макробиблиотек

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

import from.

Объявление внешних макросов с помощью директивы импорта предписывает ассемблеру включить определения указанных макросов из некоторой внешней макробиблиотеки. имя_библиотеки считается чистым именем файла макробиблиотеки; оно должно быть задано без пути и может быть задано без расширения, если расширение файла библиотеки не отличается от стандартного (.mlb).

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

Примеры объявлений внешних макросов:

import mode_constants from com_decl.mlb;

import mode_constants, irqtab_layout from

com_decl.mlb;

import from com_decl.mlb;

Здесь первая директива включает из библиотеки com_decl.mlb один, указанный, макрос, вторая - два макроса, третья - все макросы библиотеки.

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

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

ПРИМЕРЫ ПРОСТЕЙШИХ ПРОГРАММ

Пример 1: Пример использования макросов в программе

Исходный текст примера, используемого в данном уроке, содержится в файле step13.asm в каталоге: ..\Tutorial\Step13

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

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

Файл “main.cpp”

// функция Copy объявлена внешней с Си-связыванием

extern " C" void Copy( long *Src, long *Dst );

long A[16]; // массив исходных данных

long B[16]; // массив результатов

int main()

{

for (int i=0; i< 16; i++)

A[i] = 0x0807060504030201*i;

Copy( A, B ); // вызов функции Copy

return 0;

}

 

Файл “step13.asm”

global _Copy: label; // объявление глобальной метки _Copy

// описание макроса, предназначенного для копирования одного массива 64-разрядных слов в

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

macro AAA (Arg1, Arg2, Arg3)

own Loop: label; // объявление метки внутри макроса

gr1 = Arg3; // в gr1 загружается количество итераций

gr1--; // установка флага для вхождения в цикл

< Loop>

// инструкция, содержащая команду отложенного перехода

if > delayed goto Loop with gr1--;

gr2, ar2 = [Arg1++];

[Arg2++] = ar2, gr2;

end AAA;

begin ".textAAA"

< _Copy>

ar5 = ar7 – 2;

push ar0, gr0;

push ar1, gr1;

push ar2, gr2;

ar0 = [--ar5]; // в ar0 адрес исходного массива А

ar1 = [--ar5]; // в ar1 адрес массива результата В

AAA(ar0, ar1, 16); // подстановка макроса ААА

pop ar2, gr2;

pop ar1, gr1;

pop ar0, gr0;

return;

end ".textAAA";

Комментарии к Примеру

Функция Copy использует макрос ААА.

AAA(ar0, ar1, 16);

В качестве первого параметра передается массив А, второй параметр – массив В, третий – число 16.

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

macro AAA (Arg1, Arg2, Arg3)

end AAA;

Описание тела макроса начинается с ключевого слова

macro

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

Заканчивается описание закрывающей скобкой

end

после которой указано имя макроса.

При подстановке макроса в тело программы формальные параметры заменяются фактическими значениями.

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

Подробнее об использовании макросов см. в приложении

A.2.Использование Макросов в Языке Ассемблера.

Если внутри тела макроса требуется использовать метку, то при ее объявлении требуется указать ключевое слово own.

own Loop: label;

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

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

import from M.mlb;

где M.mlb – библиотека макросов, в которой находится необходимый макрос.

Компиляция Примера

Для компиляции примера необходимо в командной строке ввести

команду:

nmcc -g -m Step13.asm main.cpp –oStep13.abs

Пример 2: Создание Библиотеки Макросов

Исходный текст примера содержится в файле step13а.asm в каталоге:

..\Tutorial\Step13а

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

Файл “macros1.asm” Макрос осуществляет копирование одного массива данных в другой.

macro AAA (Arg1, Arg2, Arg3)

own Loop: label;

gr1 = Arg3;

gr1--;

< Loop>

if > delayed goto Loop with gr1--;

gr2, ar2=[Arg1++];

[Arg2++]=ar2, gr2;

end AAA;

Файл “macros2.asm”

macro Push_Pop (Arg1)

.if Arg1 xor 1; // начало блока услованой компиляции

push ar0, gr0;

push ar1, gr1;

push ar2, gr2;

.endif; // конец блока условной компиляции

.if Arg1; // начало блока условной компиляции

pop ar2, gr2;

pop ar1, gr1;

pop ar0, gr0;

.endif; // конец блока условной компиляции

end Push_Pop;

Комментарии к Примеру

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

Блоки условной компиляции формируются с помощью директивы.if.

Создание библиотеки макросов

Для создания библиотеки, содержащей описания макросов AAA и Push_Pop в командной строке требуется ввести сначала:

asm -mmacros.mlb macros1.asm

Таким образом, создается библиотека macros.mlb, содержащая макрос ААА.

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

asm -mmacros.mlb -a macros2.asm

Более подробное описание макросов и примеров работы с ними приведено в приложении A.2.Использование Макросов в Языке Ассемблера.

После того, как сформирована макробиблиотека, можно осуществлять подстановку макросов в программу.

Файл “main.cpp”

// функция Copy объявлена внешней с Си-связыванием

extern " C" void Copy( long *Src, long *Dst );

long A[16]; // массив исходных данных

long B[16]; // массив результатов

int main()

{

for (int i=0; i< 16; i++)

A[i] = 0x0807060504030201*i;

Copy( A, B ); // вызов функции Copy

return 0;

}

Файл “step13a.asm”

global _Copy: label; // объявление глобальной метки _Copy

import from macros.mlb;

begin ".textAAA"

< _Copy>

ar5 = ar7 – 2;

Push_Pop(0); // подстановка макроса (сохранение регистров)

ar0 = [--ar5]; // в ar0 адрес исходного массива А

ar1 = [--ar5]; // в ar1 адрес массива результата В

AAA(ar0, ar1, 16); // подстановка макроса ААА

Push_Pop(1); // подстановка макроса (восстановление регистров)

return;

end ".textAAA";

Компиляция Примера

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

nmcc -g -m Step15a.asm main.cpp –I..\Include -oStep15a.abs

где Include – каталог, в котором содержатся необходимые макробиблиотеки.

ПОРЯДОК ВЫПОЛНЕНИЯ РАБОТЫ

Практическая часть работы предполагает разработку программы на ассемблере с использованием макросов. Программа должна содержать 2 макроса: первый заполняет блок памяти массивом из чисел (см. задание 1 предыдущей лабораторной работы), а второй выполняет обработку этого массива в соответствии с вариантом задания для бригады. Номер варианта задания для второго макроса соответствует номеру бригады.

Для отладки программы воспользуемся специальным отладчиком emudbg.exe, поставляемым вместе с пакетом разработчика для процессора NM 6403.

Задания:

1 Вычислить контрольную сумму блока памяти (количество единичных бит) и записать её сразу за концом блока.

Рекомендации по выполнению: Воспользуйтесь операцией взвешенного суммирования, разбив рабочую матрицу на 32 строки и 1 столбец. На первом этапе, вычислите сумму четных единичных бит (нумерация, как и для элементов блока памяти начинается с нуля, а ноль – четное число) блока памяти. Полученные восемь 64-разрядных частичных суммы запишите в память для их временного хранения. На втором этапе, вычислите сумму нечетных единичных бит. На третьем этапе, просуммируйте частичные суммы четных и нечетных бит. Выгрузите полученные восемь 64-разрядных частичных суммы в память для их временного хранения. На четвертом этапе, просуммируйте полученные частичные суммы на скалярном процессоре (см. разобранный пример для 11 варианта) и запишите результат в память. Для того чтобы получить доступ к четным/нечетным битам входа Х, необходимо воспользоваться блоком маскирования задав соответствующие векторы масок:

EvenMask: long = 05555555555555555hl; // маска для четных бит (0101).

OddMask: long = 0aaaaaaaaaaaaaaaahl; // маска для нечетных бит (1010).

Вектор масок следует хранить в ram, причем столько 64-разрядных слов, сколько раз выполняется векторная команда (в нашем случае – 8). Кроме того, при суммировании нечетных бит, необходимо подключить регистр сдвига, т.к. разрядность элементов входа Х – 2 бита. Во избежание путаницы, следует четко представлять последовательность выполнения всех этих операций в процессоре (см. предыдущую работу).

2 Прибавить всем четным элементам разрядностью 16 бит сегодняшнее число. Затем, вычислить сумму 0-го и 1-го 64-разрядных элементов и записать её сразу за концом блока.

3. Умножить каждый элемент блока памяти разрядностью 8 бит на количество человек в бригаде. Затем, найти разность между 2-ым и 0-ым 32-разрядными элементами и записать её сразу за концом блока 64-разрядным словом с обнулением старших 32 разрядов этого слова.

4. Вычесть из каждого нечетного элемента разрядностью 32 бита предыдущий (четный) элемент. Затем, найти результат логического «или» 0-го и 4-го элементов разрядностью 16 бит и записать его сразу за концом блока 64-разрядным словом с обнулением старших 48 разрядов этого слова.

5. Поменять местами соседние четные и нечетные 16-разрядные элементы. Затем, найти результат логического «и» 0-го и 1-го 64-разрядных слов и записать его сразу за концом блока.

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

7. Проинвертировать побитно блок памяти, а затем найти результат логического «и» исходного и проинвертированного блока.

Рекомендации по выполнению: Воспользуйтесь операцией or или and в АЛУ, подключив инверсию входа Х, а на вход Y подав соответствующее значение в зависимости от используемой операции. В данном примере можно обойтись без выгрузки промежуточных результатов в память, воспользовавшись возможностью работы afifo одновременно как на чтение (из головы) так и на запись (в хвост).

8. Замените все неотрицательные 4-разрядные элементы нулём, а отрицательные – минус единицей. Затем, замените все -1 на 1, а нулевые элементы оставьте без изменений.

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

9. Выполнить арифметическую активацию всех 4-разрядных элементов порогами [-4; 3] (см. предыдущую работу). Затем найти результат «исключающего или» 0-го и 7-го (последнего) 64-разрядных элементов, и записать его сразу за концом блока.

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

11. Прибавить всем четным 16-разрядным элементам следующий за ними нечетный элемент, умноженный на 2 и уменьшенный на 1. После чего, найти результат операции исключающего или над 0-ым и 4-ым 16-разрядными элементами блока памяти, результат которой записать в память 64-разрядным словом сразу за концом блока с обнулением оставшихся 48 старших бит слова. Затем, найти сумму всех нечетных 8-разрядных элементов блока памяти в формате 32-разрядного слова.

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

 

ЛАБОРАТОРНАЯ РАБОТА №4

 

Кодирование и декодирование информации в нейромикропроцессоре NeuroMatrix ® NM 640Х

Цель работы:

  • Научиться работать с эмулятором векторных команд, обеспечивающим оахоаюльку написание, отладку и получение генерируемого, компилированного и сохраняемого кодов с контролем реальных аппаратных ресурсов и распределения памяти процессора Л1879ВМ1, Л1879ВМ2 ( NM 6403/6404).
  • Научиться шифровать: кодировать и декодировать информацию по ГОСТу 28147-89
  • Применить данный эмулятор векторных команд для шифрования по вышеуказанному ГОСТу.

ТЕОРЕТИЧЕСКАЯ ЧАСТЬ


Поделиться:



Популярное:

  1. III. Практическое использование водорослей.
  2. IV. Виды бланков документов, их изготовление и использование
  3. VI. Переведите на английский язык предложения с использованием форм простого будущего времени, либо других способов выражения будущего.
  4. Алгоритм выполнения чертежей с использованием
  5. АЛФАВИТНЫЙ УКАЗАТЕЛЬ ТЕРМИНОВ НА АНГЛИЙСКОМ ЯЗЫКЕ
  6. АЛФАВИТНЫЙ УКАЗАТЕЛЬ ТЕРМИНОВ НА РУССКОМ ЯЗЫКЕ
  7. АЛФАВИТНЫЙ УКАЗАТЕЛЬ ТЕРМИНОВ НА ФРАНЦУЗСКОМ ЯЗЫКЕ
  8. Более сложное использование вторичного подкрепления
  9. Введение. Язык и речь. Понятие о литературном языке и языковой норме.
  10. Виды сказуемых в русском языке
  11. Вопрос 40. Использование индексов в экономико-статистических расчетах. Индекс потребительских цен. Индекс цен производителей промышленной продукции.
  12. Вопрос Использование наступательных стратегий для сохранения конкурентного преимущества


Последнее изменение этой страницы: 2016-08-31; Просмотров: 1111; Нарушение авторского права страницы


lektsia.com 2007 - 2024 год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! (0.054 с.)
Главная | Случайная страница | Обратная связь