Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка (НСиНК) - лабораторные работы.doc
Скачиваний:
1
Добавлен:
01.03.2025
Размер:
477.18 Кб
Скачать

Пример 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 – каталог, в котором содержатся необходимые макробиблиотеки.

4. Порядок выполнения работы

Практическая часть работы предполагает разработку программы на ассемблере с использованием макросов. Программа должна содержать 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-разрядного слова.

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