Студопедия

КАТЕГОРИИ:

АвтоАвтоматизацияАрхитектураАстрономияАудитБиологияБухгалтерияВоенное делоГенетикаГеографияГеологияГосударствоДомЖурналистика и СМИИзобретательствоИностранные языкиИнформатикаИскусствоИсторияКомпьютерыКулинарияКультураЛексикологияЛитератураЛогикаМаркетингМатематикаМашиностроениеМедицинаМенеджментМеталлы и СваркаМеханикаМузыкаНаселениеОбразованиеОхрана безопасности жизниОхрана ТрудаПедагогикаПолитикаПравоПриборостроениеПрограммированиеПроизводствоПромышленностьПсихологияРадиоРегилияСвязьСоциологияСпортСтандартизацияСтроительствоТехнологииТорговляТуризмФизикаФизиологияФилософияФинансыХимияХозяйствоЦеннообразованиеЧерчениеЭкологияЭконометрикаЭкономикаЭлектроникаЮриспунденкция

Примеры простейших программ




Пример 1: Простейшая Программа на Языке Ассемблера

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

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

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

<__main> // определение глобальной метки

gr0 = 1; // загрузка константы в первый общий регистр

gr1 = 2; // загрузка константы во второй общий регистр

gr7 = gr0 + gr1; // нахождение суммы

return; // возврат из функции, возвращаемое значение хранится в gr7

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

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

Пример начинается с объявления глобальной (global) метки __main (два подчёркивания перед словом main обязательны), которая будет в данном случае определять адрес в памяти той команды, с которой начинается тело основной программы.

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

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

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

ПримечаниеРекомендуется имя секции кода начинать с префикса text, например: «textMyCodeSection». Дизассемблер (программа dump.exe), разбирая первые символы имени секции, поймёт, что это код программы и представит её содержимое в виде дизассемблированных инструкций. В противном случае он оставит содержимое секции в виде бинарного кода.

За открывающей скобкой begin “.textAAA” следует определение метки:

<__main>

Метка помечает ту команду, которая следует после неё до ближайшей ";". В приведённом выше примере меткой помечается инструкция gr0 = 1;.

Инструкции:

gr0 = 1;

gr1 = 2;

представляют собой команды инициализации константой регистров общего назначения gr0 и gr1.

Инструкция:

gr7 = gr0 + gr1;

выполняет арифметическую операцию суммирования содержимого регистров gr1 и gr2, а результат заносит в регистр gr7.

Регистр gr7 используется для хранения возвращаемого значения при выходе из функции.

Тело программы заканчивается командой возврата из подпрограммы:

return ;

Последней строкой примера стоит закрывающая скобка секции кода.

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

Пример демонстрирует простейший метод организации цикла инструкциями <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"; // признак окончания секции кода.

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

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

Команда

if > goto Loop;

осуществляет переход на метку Loop, в случае если условие > (больше) выполнено (все сравнения осуществляются с нулём). Эта команда проверяет значение флагов, выставленных предшествующей операцией, в данном случае такой операцией является gr1-- (Для конкретного примера gr1 является счетчиком цикла, в процессоре NM6403 нет специального регистра – счётчика циклов). Установка флагов происходит только при выполнении арифметическо-логической операции в правой части скалярной команды.

Пример 3: Оптимизация Выполнения Цикла

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

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, равное количеству

// итераций в цикле.

gr1--; // переменная цикла уменьшается на 1 для входа в цикл с

// правильно выставленными условными флагами.

<Loop>

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

// Loop

if > delayed goto Loop with gr1--;

// две следующих инструкции выполняются до того, как произойдёт

// переход

[ar0++] = gr0 with gr0++ noflags;

nul;

// ------- здесь произойдёт переход на метку Loop --------------

return; // сюда перейдёт программа, когда условие не выполнится

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

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

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

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

От момента выбора команды перехода и до того, как состоится реальный переход проходит от одного до трёх тактов. За это время процессор успевает выбрать дополнительно одну-три инструкции, следующих непосредственно за инструкцией перехода. Назовём такие инструкции отложенными. Упрощённая схема выполнения перехода подразумевает, что компилятор сам рассчитывает количество отложенных инструкций и заполняет их пустыми командами (nul). Если программист для выполнения перехода использует инструкцию без ключевого слова delayed, например:

if > goto Loop;

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

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

if > delayed goto Loop with gr1--;

будут выполнены две отложенные инструкции:

[ar0++] = gr0 with gr0++ noflags;

null;

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

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

if > delayed goto Loop with gr1--;

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

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










Последнее изменение этой страницы: 2018-05-10; просмотров: 235.

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