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


ЭЛЕМЕНТЫ ЯЗЫКА АССЕМБЛЕРА ПРОЦЕССОРА NM 6403



Формат ассемблерных инструкций

Процессор NM6403 работает с машинными командами 32-х и 64-х разрядного формата, причем в одной машинной команде содержится две операции процессора. В этом смысле NM6403 представляет собой скалярный микропроцессор со статической Very Long Instruction Word ( V LIW) - архитектурой. При этом используются короткие и длинные инструкции. При чем короткие инструкции не содержат константы и имеют разрядность 32 бита. А длинные инструкции содержат в коде команды 32-х разрядную константу. Поэтому их разрядность составляет 64 бита. Процессор адресуется к 32-х разрядным словам. На хранение коротких инструкций отводится одна ячейка памяти, для длинных – две.

Примечание Длинные инструкции всегда располагаются по четным адресам.

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

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

Все инструкции процессора NM6403 делятся на два типа:

  • скалярные инструкции, которые управляют работой скалярного RISC-ядра, таймеров, осуществляют загрузку/чтение всех регистров (доступных по чтению/записи) за исключением векторных регистров, образующих очереди FIFO;
  • векторные инструкции, которые управляют работой векторного процессора.

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

Пример скалярной инструкции процессора:

gr 0 = [ ar 0++] with gr 1 = gr 3 + gr 0;

gr 1 = gr 3 + gr 0 – правая часть инструкции, арифметическая операция.

gr 0 = [ ar 0++] – левая часть инструкции, адресная операция.

В языке ассемблера левая или правая часть инструкции может быть опущена, однако поскольку процессор не может выполнить только левую или только правую часть команды, вместо опускаемой части при компиляции автоматически добавляется пустая операция nul. То есть ассемблерная инструкция, записанная как: gr0 = [ar0++];

трактуется ассемблером как: gr 0 = [ ar 0++] with nul ;

Аналогично с левой частью: gr1 = gr3 + gr 0;

рассматривается как: nul with gr 1 = gr 3 + gr 0;

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

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

Векторные инструкции процессора

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

rep 32 data = [ar1++] with vsum, data, afifo;

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

В случае, если левая часть инструкции опущена, поле повторения и слово-связка with остаются при написании инструкции, например:

rep 16 with ram - 1; // правильная инструкция

Любые другие формы записи инструкции, как то

rep 16 ram - 1; или with ram - 1; // содержат ошибки

являются ошибочными, о чем сообщит компилятор.

Регистры процессора

Основные регистры

К основным регистрам процессора относятся 8 адресных регистров: ar0 - ar7( sp ) и 8 регистров общего назначения: gr0 - gr0, которые используются в большинстве вычислитель­ных операций процессора. Все они 32-х разрядные, доступны как по чтению, так и по записи.

Адресные регистры

Адресные регистры делятся на две равноправные группы. В первую входят ar0-ar3, а во вторую ar4..ar7. Это связано с наличием двух адресных устройств в процессоре.

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

Примеры использования адресных регистров:

ar0 = ar5; // копирование.

ar2 = ar3 + gr3; // модификация.

[ar4++] = gr7 with gr7 -= gr4; // запись в память.

Адресный регистр ar7 используется процессором в качестве указателя стека адресов возврата sp(Stack Pointer). Это означает, что ar7 модифицируется автоматически, когда происходит вызов функции или прерывания, а также возврат из функции или из прерывания.

Регистры общего назначения

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

[gr0] = gr4; // запись значения регистра gr4 в память

// по адресу, хранящемуся в gr0.

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

Примеры использования регистров общего назначения:

gr0 = gr5; // копирование.

gr2 = gr1 + gr3; // модификация.

[ar4++] = gr7 with gr7 -= gr4; // запись в память.

Примечание В процессоре NM6403 не предусмотрены специальные регистры для организации программных циклов.

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

Пример 1: Организация циклов и доступ к памяти

Пример демонстрирует простейший метод организации цикла инструкциями < Loop> - начало цикла и if > goto Loop; - конец цикла при заполнении массива данных возрастающими значениями.

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

nobits ".MyData1" // секция неинициализированных данных.

global C: word[16]; // объявили массив из 16 32-разрядных слов

end ".MyData1";

begin ". textAAA " // начало секции кода.

< __main>

ar0 = C; // в ar0 загрузили адрес массива С.

gr0 = 0; // в gr0 загрузили значение 0.

gr1 = 16; // в gr1 загрузили значение 16, равное количеству итераций в цикле.

< Loop>

[ar0++] = gr0; // в память по адресу ar0 записываем

// содержимое gr0, а затем увеличиваем

// адрес на 1 (пост-инкрементация).

gr0++; // увеличили значение gr0 на 1

gr1--; // уменьшили значение gr1 на 1, таким образом установили флаг в регистре pswr для дальнейшей проверки

if > goto Loop; // если условие выполнено, осуществляется переход на метку Loop.

return;

end ".textAAA"; // признак окончания секции кода.

Комментарии. В примере массив С в цикле последовательно заполняется возрастающими значениями. Цикл организован путем перехода на заданную метку при выполнении определенных условий (с помощью команд условного перехода).

Пример 2: Копирование массива данных на скалярном процессоре

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

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

data ".MyData" // секция инициализированных данных массив А из 16 64-разрядных слов заполняется начальными значениями

global A: long[16] = (0l, 1l, 2l, 3l, 4l, 5hl, 6l, 7l, 8l, 9l,

10l, 0Bhl, 0Chl, 13l, 14l, 15l);

end ".MyData";

nobits ".MyData1" //секция неинициализированных данных.

global B: long[16]; //объявляется массив В из 16 64-разрядных слов

global C: long[16]; // объявляется массив С из 16 64-разрядных слов

end ".MyData1";

begin ".textAAA" // начало секции кода.

< __main> // простое копирование массива данных на скалярном процессоре

ar0 = A;

ar1 = B;

gr1 = 32; // счётчик цикла ( 32 цикла для копирования 16 64-bit слов)

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

< Loop> // если условие выполнено, осуществляется отложенный переход на метку Loop

if > delayed goto Loop with gr1--; // чтение из памяти 32-разрядного слова

gr2 = [ar0++]; // запись в память 32-разрядного слова

[ar1++] = gr2; // копирование массива данных при помощи регистровых пар

ar0 = A;

ar1 = B;

gr1 = 16; // счётчик цикла ( 16 циклов для копирования 16 64-bit слов)

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

< Loop1> // если условие выполнено, осуществляется отложенный переход на метку Loop1

if > delayed goto Loop1 with gr1--;

// чтение из памяти 64-разрядного слова

gr2, ar2 = [ar0++];

// запись в память 64-разрядного слова

[ar1++] = ar2, gr2;

return;

end ".textAAA"; // признак окончания секции кода.

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

Во второй части примера копирование происходит через регистровую пару ar2, gr2 (в регистровой паре каждому адресному регистру поставлен в соответствие регистр общего назначения с тем же номером). За один цикл чтения/записи переносится целиком 64-разрядное слово, поэтому количество циклов копирования равно шестнадцати.

При чтении из памяти в регистровую пару ar2, gr2 = [ar0++]; всега младшая часть 64-разрядного слова попадает в arX, старшая – в grX независимо от того, в каком порядке перечислены регистры в паре. Те же правила действуют при записи содержимого регистровой пары в память. По младшему адресу всегда записывается содержимое регистра arX, по старшему - grX. Таким образом, команда [ar1++] = gr2, ar2; запишет данные в память в том же порядке, в каком они были считаны, независимо от того, в какой последовательности перечислены регистры регистровой пары.

Другим важным моментом, на который стоит обратить внимание, является то, как изменяются значения адресных регистров, используемых для доступа к памяти. И в первой, и во второй части примера используется одна и та же форма записи для инкрементации регистров ar0 и ar1. Однако в первой части, когда выполняется 32-х разрядный доступ к памяти, значения адресных регистров увеличиваются на единицу, а во второй на двойку.

Процессор автоматически распознаёт, какой тип доступа к памяти используется в заданной инструкции – 32-х или 64-х разрядный.

Наличие в инструкции регистровой пары или 64-х разрядного регистра управления приводит к тому, что доступ к памяти ведётся 64-х разрядными словами. Но поскольку единица адресации - 32-х разрядное слово, то при 64-х разрядном доступе простая инкрементация адресного регистра приводит к увеличению его значения на два, например:

gr2 = [ar0++]; // ar0 увеличивается на 1

ar2, gr2 = [ar0++]; // ar0 увеличивается на 2

Пример 3: Копирование массива данных на векторном процессоре

Пример демонстрирует копирование массива 32-разрядных слов с помощью векторного процессора.

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

data ".MyData" // секция инициализированных данных массив А из 16 32-разрядных слов заполняется начальными значениями

global A: word[16] = (0, 1, 2, 3, 4, 5h, 6, 7, 8, 9, 10, 0Bh, 0Ch, 13, 14, 15);

end ".MyData";

nobits ".MyData1" // секция неинициализированных данных.

global B: word[16]; // объявляется массив В из 16

// 32-разрядных слов

global C: word[16]; // объявляется массив С из 16

// 32-разрядных слов

end ".MyData1";

begin ". textAAA " // начало секции кода.

< __main> // копирование массивов данных

ar0 = A; // с помощью векторного процессора

ar1 = C; // массив А подаётся на векторное АЛУ и попадает в afifo без изменений

rep 8 data = [ar0++] with data; // сохранение во внешней памяти содержимого afifo, заполненного предыдущей векторной инструкцией.

rep 8 [ar1++] = afifo;

return;

end ".textAAA"; // признак окончания секции кода.

Комментарии. Обязательным атрибутом векторной инструкции является количество повторений, определяющее, какое количество 64-х разрядных векторов данных обрабатывается данной инструкцией. В этом смысле векторные инструкции являются SIMD (Single Instruction Multiple Data) инструкциями, выполняя одно и то же действие над несколькими векторами данных.

Команда

rep 8 [ar1++] = afifo;

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

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

Пример 4: Операция взвешенного суммирования

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

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

data ".MyData" //секция инициализированных данных исходный вектор

A: long = 8877665544332211hl;

// место для хранения результата вычислений

B: long = 0l; // массив Matr содержит значения для заполнения матрицы весовых коэфициентов

Matr: long[8] = (0100000000000000hl,

0001000000000000hl,

0000010000000000hl,

0000000100000000hl,

0000000001000000hl,

0000000000010000hl,

0000000000000100hl,

0000000000000001hl);

end ".MyData";

begin ".textAAA" // начало секции кода.

< __main>

ar1 = Matr;

nb1 = 80808080h; // матрица делится на 8 столбцов по 8 бит

sb = 03030303h; // матрица делится на 8 строк

// весовые коэффициенты загружаются в буфер wfifo

rep 8 wfifo = [ar1++];

ftw; // весовые коэффициенты пересылаются в теневую матрицу с перекодировкой. Эта инструкция всегда выполняется 32 такта.

wtw; // весовые коэф.копируются из теневой матрицы в рабочую

ar2 = A;

ar4 = B; // операция взвешенного суммирования, переставляющая местами байты вектора.

rep 1 data = [ar2] with vsum, data, 0;

// результат операции выгружается из afifo в память

rep 1 [ar4] = afifo;

return;

end ".textAAA"; // признак окончания секции кода.

Комментарии. Задачей данного примера является перестановка порядка элементов в 64-разрядном векторе из состояния A = 8877665544332211hl в состояние В = 1122334455667788hl. Эта перестановка выполняется на устройстве умножения векторного процессора при помощи операции взвешенного суммирования. Основная идея этого преобразования:

Рисунок 3.1 Перестановка Элементов Вектора на Матричном Умножителе

Команда rep 8 wfifo = [ar1++]; осуществляет загрузку весовых коэффициентов из памяти в регистр-контейнер wfifo. Загрузку можно осуществлять и по частям, но так, чтобы не произошло переполнения. Контейнер wfifo имеет глубину в тридцать два 64-х разрядных слова.

Команда ftw; выполняет перекодировку весовых коэффициентов, расположенных в wfifo, в специальный вид, в котором они хранятся в теневой матрице. Эта операция всегда выполняется за 32 такта, однако, она может выполняться параллельно с другими векторными инструкциями.

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

Инструкция

rep 1 data = [ar2] with vsum, data, 0;

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

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

Практическая часть работы предполагает разработку несложной программы на ассемблере. Программа заполняет блок памяти возрастающими значениями, а затем выполняет некоторые манипуляции над ним. Блок памяти (или массив) будем рассматривать состоящим из элементов определённой разрядности. Для простоты, будем брать только кратные двум разрядности (например, 2, 4, 8, 16, 32, 64 бит) чтобы блок всегда можно было представить из целого количества таких элементов. При этом, элементы имеют порядковые номера от начала блока: 0, 1, 2, … Под четными/нечетными элементами будем понимать элементы с четными / нечетными порядковыми номерами. Ещё раз, следует обратить внимание на то, что нумерация начинается с нуля! , а ноль – это четное число. Так же, следует уточнить, что понимается под положительными/отрицательными числами. Все числа, старший разряд которых =1 процессор воспринимает как отрицательные, а все остальные – как положительные.

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

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

Задание:

1. Заполнить блок памяти размером в 8 64-разрядных слов (или, что то же самое, – 16 32-разрядных слов) элементами длинной 32 бита возрастающими с INC на INC, где INC = текущий год * (номер бригады + количество человек в бригаде + сумма цифр номера группы). Написать программу для выполнения этого задания (см. разобранный пример для 11 варианта), скомпилировать её в выполняемый файл (*. abs ) и отладить её на отладчике emudbg. exe. Зафиксировать в отчете полученный блок памяти с указанием его начального и конечного адреса.

Для написания текста программы следует воспользоваться любым текстовым редактором не сохраняющим символы форматирования (например, notepad. exe ). Файл следует сохранить с расширением *. asm.

Для компиляции полученного файла необходимо поместить его в каталог, где установлен пакет разработчика для NM 6403. Это может быть каталог: С: \ Program Files \­ Module \ Nmsdk \ bin \ или другой по указанию инженера. Из этого каталога следует запустить программу компилятора следующей командой: nmcc -g step1.asm libc.lib –m, где step1. asm – имя файла с исходными текстами вашей программы. Рекомендуется создать командный (*. bat ) файл с этой командой, чтобы не вводить её каждый раз, а запускать уже этот файл. Если компиляция пройдёт успешно, то в этом же каталоге будут созданы несколько файлов с тем же именем, но с другими расширениями. Нас из них будут интересовать следующие: *. abs – выполняемый файл открываемый из отладчика emudbg. exe, *. map – файл карты памяти в котором можно просмотреть начальные адреса переменных (то, что объявляется в секциях данных) в памяти для наблюдения за их содержимым в процессе отладки. Если же в процессе компиляции будут обнаружены ошибки в тексте программы, компилятор сообщит о них выводом сообщений с указанием номера строки в которой обнаружена ошибка.

Для отладки скомпилированной программы следует запустить программу emudbg. exe всё из того же каталога. Затем, в главном меню выбрать пункт: Цель-> Загрузить программу и в появивадшемся диалоге указать *. abs -файл вашей программы. Чтобы просмотреть различные ресурсы процессора, память и дизассемблированный или исходный код программы следует обратиться к соответствующим подпунктам меню Вид. Рекомендуется, одновременно следить как минимум за содержимым: памяти, используемых программой скалярных и векторных регистров, конфигурацией рабочей матрицы и текущей выполняемой строкой исходного текста. Для доступа к ним необходимо открыть следующие пункты меню Вид: Память, Регистры, Специфика целевой среды и Исходные тексты-> Ваш файл *. asm. При этом, память во многих случаях будет удобнее просматривать не 32-разрядными словами, а 64-разрядными. Для этого: Щелчок правой кнопкой мыши в окне Память-> 64-битные слова. На панели инструментов отладчика расположены кнопки быстрого доступа к наиболее используемым командам, всплывающие подсказки поясняют их назначение. Нам понадобятся: Шаг простой / Шаг обходящий – любой из них для выполнения текущей команды; Снять / поставить точку останова; Запуск / Анимация – любая из них для выполнения уже хорошо отлаженной части программы до точки останова, чтобы не использовать многократно Шаг простой / Шаг обходящий. Чтобы выгрузить программу из отладчика, но оставить конфигурацию процессора и содержимое памяти без изменений следует выбрать: Цель-> Выгрузить программу. Если же необходим полный сброс процессора в исходное состояние, то следует выбрать: Цель-> Перезагрузить цель.

2. Выполнить обработку полученного блока памяти (массива) в соответствии с вариантом для вашей бригады:

Вариант 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 разрядов этого слова.

Рекомендации по выполнению: Для выполнения первой части задания воспользуйтесь операцией взвешенного суммирования. Задайте необходимое разбиение рабочей матрицы и весовые коэффициенты. Для выполнения второй части задания следует воспользоваться соответствующей операцией на векторном АЛУ. При этом не забывайте, что разбиение на элементы при использовании векторного АЛУ одинаково для входов Х и Y, и задаётся регистром nb (см. разобранный пример для 11 варианта). Ответьте на вопрос – влияет ли разбиение на результат вашей операции на ВАЛУ?

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

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

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

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

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

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

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

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

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

 

КОНТРОЛЬНЫЕ ВОПРОСЫ

 

  1. Перечислите основные внутренние блоки процессора NM 6403 и поясните их назначение.
  2. Какова разрядность интерфейса с внешней памятью процессора NM 6403?
  3. Состав и назначение скалярного процессора.
  4. Перечислите основные элементы векторного процессора и поясните их назначение.
  5. Какова разрядность узлов векторного процессора?
  6. Как может быть сформировано и обработано слово упакованных векторных данных?
  7. Какие операции способен выполнять векторный процессор?
  8. Поясните суть операции взвешенного суммирования и приведите примеры её использования.
  9. Какие операции способно выполнять векторное АЛУ? Чем оно отличается от скалярного АЛУ?
  10. Каковы особенности выполнения операций на векторном АЛУ при возникновении переполнений?
  11. Чем определяется разбиение на элементы при операциях на рабочей матрице и на векторном АЛУ?
  12. Поясните суть операции маскирования с векторным умножением.
  13. Поясните суть операции логического маскирования, с какими операциями она используется?
  14. Поясните суть операции арифметической активации, с какими операциями она используется?
  15. Поясните суть операции логической активации, с какими операциями она используется?
  16. Поясните суть операции циклического сдвига вправо операнда Х, с какими операциями она используется?
  17. Каков порядок выполнения преобразований над данными на векторном процессоре?

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

Программирование нейромикропроцессора NeuroMatrix ® NM 6403 с использованием макросов

Ц ель работы: ознакомление с языком ассемблера нейромикропроцессора NeuroMatrix ® NM 6403 (Л18789 ВМ1) и правилами описания и использования макросов в программе..

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

По материалам разделов 2 и 3 изучить структуру формат ассемблерных инструкций структуру микрокоманд (МК), порядок ввода данных, кодирование и выполнение МК.

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

Выполнить упражнения из раздела 5 по указанию преподавателя.


Поделиться:



Популярное:

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


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