Основы программирования на Ассемблере
СОДЕРЖАНИЕ
Введение
.
Цифровые узлы комбинационного и последовательного типа
.1
Моделирование цифровых узлов комбинационного и последовательного типа
.Основы
программирования на Ассемблере
.1
Арифметические команды, команды передачи
.2
Манипуляции над битами. Строковые операции
.
Программирование с использованием MASM
.1
Пакет MASM. Структура программы
.2
Совместное использование языка Ассемблер с другими языками программирования
.3
Команды управления циклами. Команды работы со строками. Вывод на экран в текстовом
режиме
Заключение
Литература
ассемблер команда бит строка
ВВЕДЕНИЕ
С 24 февраля 2014 года по 1 марта 2014 года я
проходил практику по дисциплине «Основы микропроцессорной техники» на базе ЧУ
ТМК «Мирас».
Целью практики по основам микропроцессорной
техники является получение практических навыков по моделированию цифровых
устройств комбинационного и последовательного типов, изучение и
программирование на языке ассемблер с использованием MASM.
Микропроцессорная техника сейчас все более
широко входит в нашу жизнь, постепенно замещая и вытесняя традиционную цифровую
технику на «жесткой логике». Универсальность, гибкость, простота проектирования
аппаратуры, практически неограниченные возможности по усложнению алгоритмов
обработки информации - все это обеспечивает микропроцессорной технике большое
будущее. На долю традиционной цифровой техники остаются только узлы и
устройства, требующие максимального быстродействия, а также устройства с
простейшими алгоритмами обработки информации. Обычная цифровая техника также
применяется в настоящее время для увеличения возможностей микропроцессорных
систем, для их сопряжения с внешними устройствами, для увеличения их
возможностей, то есть играет по сути вспомогательную роль. Таким образом,
традиционную цифровую технику ждет, по-видимому, в самом недалеком будущем
участь аналоговой техники, область применения которой в свое время сильно
сузилась с появлением цифровой техники.
На время прохождения учебной практики ставились
следующие задачи:
Повторение основных узлов и устройств, входящих
в элементную базу микропроцессорной техники.
Строить функциональные схемы узлов.
Определять классификацию и функциональные
возможности триггеров, регистров, счетчиков.
Получить представление о принципах
программирования на машинном уровне на примере языка ассемблер.
1. ЦИФРОВЫЕ УЗЛЫ КОМБИНАЦИОННОГО И
ПОСЛЕДОВАТЕЛЬНОГО ТИПА
.1 МОДЕЛИРОВАНИЕ ЦИФРОВЫХ УЗЛОВ КОМБИНАЦИОННОГО
И ПОСЛЕДОВАТЕЛЬНОГО ТИПА
Для построения цифровых систем, кроме
комбинационных узлов, требуются последовательные узлы, логическое состояние
которых определяется последовательностью поступления входных сигналов.
Последовательная схема представляет собой автомат для выполнения логических
операций, обладающий способностью запоминания отдельных состояний переменных. В
отличие от схем комбинационного типа выходные переменные зависят не только от
входных переменных, но и от текущего состояния устройства. Таким образом, для
построения цифровых систем требуются элементы памяти, осуществляющие хранение
двоичной информации в течение требуемого времени. В качестве элемента памяти в
цифровых микросхемах используется бистабильная ячейка (БЯ), представляющая
собой два инвертирующих логических элемента (чаще всего ИЛИ-НЕ или И-НЕ),
соединенных перекрестными связями.
На основе элементов памяти строятся триггеры -
электроны схемы, имеющие два устойчивых состояния, которые устанавливаются при
подаче соответствующей комбинации на управляющие входы триггера и сохраняются в
течение заданного времени после окончания действия этих сигналов. В зависимости
от комбинаций сигналов, управляющих переключением, триггеры делятся на ряд
типов: RS, JK, Т, D.
В цифровых устройствах используется большое
число различных триггеров, которые классифицируются по ряду признаков: способу
записи информации, логической структуре, типу функционирования, элементной базе
Система схемотехнического моделирования
Electronics Workbench предназначена для моделирования и анализа электрических
схем. Electronics Workbench может проводить анализ схем на постоянном и
переменном токах. При анализе на постоянном токе определяется рабочая точка
схемы в установившемся режиме работы. Результаты этого анализа не отражаются на
приборах, они используются для дальнейшего анализа схемы. Анализ на переменном
токе использует результаты анализа на постоянном токе для получения
линеаризованных моделей нелинейных компонентов. Анализ схем в режиме АС может
проводиться как во временной, так и в частотной областях.
В Electronics Workbench можно исследовать
переходные процессы при
воздействии
на схемы входных сигналов различной формы. Программа также позволяет
производить анализ цифро-аналоговых и цифровых схем большой степени сложности.
Имеющиеся в программе библиотеки включают в себя большой набор широко
распространенных электронных компонентов. Есть возможность подключения и
создания новых библиотек компонентов. Широкий набор приборов позволяет
производить измерения различных величин, задавать входные воздействия, строить
графики. Все приборы изображаются в виде, максимально приближенном к реальному,
поэтому работать с ними просто и удобно[1].
Результаты моделирования можно вывести на
принтер или импортировать в текстовый или графический редактор для их
дальнейшей обработки.
Программа Electronics Workbench совместима с
программой P-SPICE, т.е. предоставляет возможность экспорта и импорта схем и
результатов измерений в различные ее версии.Workbench позволяет разместить
схему таким образом, чтобы были четко видны все соединения элементов и
одновременно вся схема целиком. Программа использует стандартный интерфейс
Windows, что значительно облегчает ее использование.
Для установки программы необходимы:совместимый
компьютер с модификацией процессора не ниже 486;
не менее 4 МВ свободного пространства на жестком
диске;
операционная система Microsoft Windows 3.1 или
более поздние версии;
манипулятор типа мышь.
В библиотеки компонентов программы входят
пассивные элементы, транзисторы, управляемые источники, управляемые ключи,
гибридные элементы, индикаторы, логические элементы, триггерные устройства,
цифровые и аналоговые элементы, специальные комбинационные и последовательные
схемы. Активные элементы могут быть представлены моделями как идеальных, так и
реальных элементов. Возможно также создание своих моделей элементов и
добавление их в библиотеки элементов. В программе используется большой набор
приборов для проведения измерений: амперметр, вольтметр, осциллограф,
мультиметр, Боде-плоттер (графопостроитель частотных характеристик схем),
функциональный генератор, генератор слов, логический анализатор и логический
преобразователь. Electronics Workbench позволяет строить схемы различной
степени сложности при помощи следующих операций:
выбор элементов и приборов из библиотек;
перемещение элементов и схем в любое место
рабочего поля;
поворот элементов и групп элементов на углы,
кратные 90;
копирование, вставка или удаление элементов,
групп элементов, фрагментов схем и целых схем;
изменение цвета проводников;
выделение цветом контуров схем для более
удобного восприятия;
одновременное подключение нескольких измерительных
приборов и наблюдение их показаний на экране монитора;
присваивание элементу условного обозначения;
изменение параметров элементов в широком
диапазоне.
Все операции производятся при помощи мыши и
клавиатуры. Управление только с клавиатуры невозможно.
Путем настройки приборов можно:
изменять школы приборов в зависимости от
диапазона измерений;
задавать режим работы прибора;
задавать вид входных воздействий на схему
(постоянные и гармонические токи и напряжения, треугольные и прямоугольные
импульсы).
Графические возможности программы позволяют:
одновременно наблюдать несколько кривых на
графике;
отображать кривые на графиках различными
цветами;
измерять координаты точек на графике;
импортировать данные в графический редактор, что
позволяет произвести необходимые преобразования рисунка и вывод его на
принтер.Workbench позволяет использовать результаты, полученные в программах
P-SPICE, PCB, а также передавать результаты на Electronics Workbench в эти
программы. Можно вставить схему или ее фрагмент в текстовый редактор и
напечатать в нем пояснения или замечания по работе схемы.
Дешифратор - устройство, в котором при каждой
комбинации входных сигналов, единичный сигнал формируется только на одном
определенном выходе.
Присвоив номер соответствующему выходу ДШ, можно
классифицировать его как преобразователь двоичного кода в десятичный. Очевидно,
для преобразования всех возможных комбинаций n-разрядных входных двоичных чисел
потребуется 2n-выходов ДШ. Каждый ДШ имеет 4 информационных входа и 16 выходов.
На информационные входы ДШ поступают разряды
двоичного кода с весами 8, 4, 2, 1, т.е. с десятичными эквивалентами 23, 22,
21, 20. Если на вход поступает двоичный код 1001, то с учетом десятичных
эквивалентов получим: 1001 =
. Только на выходе
№9 будет 1, а на всех остальных будет 0. В настоящее время ДШ используются как
преобразователи двоичного кода в десятичный, используются при организации
запоминающих устройств. Функциональная схема дешифратора на 16 выходов
приведена на рисунке 1.1.1 а. По такой функциональной схеме построена
микросхема К155ИД3. Условное обозначение этой микросхемы изображено на рисунке
1.1.1 б.
Рисунок 1.1.1 Функциональная схема дешифратора
на 16 выходов
Шифратор используется для преобразования
десятичного кода в двоичный. Функциональная схема шифратора, преобразующего
десятичные цифры в 4-разрядное двоичное число, приведена на рисунке 2 а, а его
условное обозначение - на рисунке 2 б.
Рисунок 1.1.2 Функциональная схема шифратора
преобразующего десятичные цифры в 4-разрядное двоичное число
При появлении сигнала логической единицы на
одном из десяти входов на четырех выходах шифратора будет присутствовать
соответствующее двоичное число. Пусть сигнал логической единицы подан на вход
7. Тогда на выходах логических элементов DD1.1, DD1.2, DD1.3 будут сигналы
логических единиц, а на выходе элемента DD1.4 - сигнал логического нуля. Таким
образом, на выходах 8, 4, 2, 1 шифратора мы получим двоичное число 0111[2].
Можно конструировать кодовые преобразователи
имеющие n-входов, связанных между собой соотношением n = 2k. Следует помнить,
что в шифраторе не используется нулевой вход, т.к. при подаче на нулевой
уровень на выходе будут нули. Серийно выпускаются и приоритетные шифраторы,
которые при одновременном воздействии на входы нескольких сигналов, в первую
очередь обслуживают тех, чей приоритет выше (очередь устанавливается заранее).
2. ОСНОВЫ ПРОГРАММИРОВАНИЯ НА АССЕМБЛЕРЕ
- язык программирования низкого уровня,
представляющий собой формат записи машинных команд, удобный для восприятия
человеком.
Команды языка ассемблера один в один
соответствуют командам процессора и, фактически, представляют собой удобную
символьную форму записи (мнемокод) команд и их аргументов.
Перевёл ОС в режим командной строки, Пуск =>
Выполнить => Вводим cmd и нажал Enter.
Появилась командная строка:
Рисунок 2.1 Командная строка Windows
Ввел в командной строке Debug, затем (?).
Рисунок 2.2 Краткий список всех команд
Краткий список всех команд:(assemble) -
Транслирование команд ассемблера в машинный код. Адрес по умолчанию - CS:0100h.
С (compare) - Сравнение содержимого двух
областей памяти. По умолчанию используется DS. В команде указывается либо длина
участков, либо диапазон адресов.(dump) - Вывод содержимого области памяти в
шестнадцатеричном и ASCII-форматах. По умолчанию используется DS. Можно
указывать длину или
диапазон.(enter) - Ввод в память данные или
инструкции машинного кода. По умолчанию используется DS .(fill) - Заполнение
области памяти данными из списка. По умолчанию используется DS . Использовать
можно как длину, так и диапазон.(go) - Выполнение отлаженной программы на
машинном языке до указанной точки останова. По умолчанию используется DS . При
этом следует убедиться, чтоIP содержит корректный адрес.(hexadecimal) -
Вычисление суммы и разности двух шестнадцатеричных величин.(input) - Считывание
и вывод одного байта из порта.(load) - Загрузка файла или данных из секторов
диска в память. . По умолчанию- CS:100h. Файл можно указать с помощью команды N
или аргумента при запускеdebug.exe.(move) - Копирование содержимого ячеек
памяти; по умолчанию используетсяDS . Можно указывать как длину, так и
диапазон.(name) - Указание имени файла для команд L (LOAD) и W (WRITE)(output)
- Отсылка байта в порт вывода.(proceed) - Выполнение инструкций CALL, LOOP, INT
(цикла, прерывания, процедур) или повторяемой строковой инструкции с префиксами
REPnn , переходя к следующей инструкции.(quit) - Завершение работы debug.exe .
Без сохранения тестируемого файла.(register) - Вывод содержимого регистров и
следующей инструкции.(search) - Поиск в памяти символов из списка. По умолчанию
используется DS. Можно указывать как длину, так и диапазон.(trace) - Пошаговое
выполнение программы. Как и в команде P , по умолчанию используется пара CS:IP
. Но для выполнения прерываний лучше пользоваться командой P .(unassemble) -
Дизассемблирование машинного кода. По умолчанию используется пара CS:IP
.(write) - Запись файла из debug.exe на диск. Необходимо обязательно задать имя
файла командой N , если он не был загружен.
)Набрал команду R. Тем самым получил и
зафиксировал дампы характерных областей RAM и ROM
Рисунок 2.3 зафиксировал дампы областей RAM и
ROM
Правила набора команд:
В debug.exe не различается регистр букв.
Пробелы в командах используется только для
разделения параметров.
Вводимые числа должны быть в шестнадцатеричной
системе счисления, без завершающей буквы h.
Сегмент и смещение записываются с использованием
двоеточия, в формате сегмент: смещение.
) Просмотр области памяти.
Команда D, позволяет просматривать содержимое
отдельных областей памяти. Для проверки размера доступной памяти ввел d 40:13 и
нажал Ввод.
Первые два байта, появившиеся в результате на
экране, содержат размер памяти в килобайтах и в шестнадцатеричном
представлении, причем байты располагаются в обратной последовательности.
Рисунок 2.4 Просмотрел содержимое отдельных
областей памяти
После ввода команды на экран выводится восемь
строк, в которых указано содержимое выбранной области памяти. Каждая строка состоит
из трех частей:
Адрес первого слева показанного байта в формате
сегмент:смещение.
) Проверка параллельных и последовательных
портов.
Первые 16 байт области данных BIOS содержат
адреса параллельных и
последовательных портов. Первые выведенные
восемь байтов указывают на адреса последовательных портов COM1-COM4. Следующие
8 байтов указывают на адреса параллельных портов LPT1-LPT4. Адрес порта 78 03 -
записывается в обращенной форме.
Рисунок 2.5 Проверка параллельных и
последовательных портов
) Проверка состояния регистра клавиатуры.
В области данных BIOS по адресу 417h находится
первый байт, который хранит состояние регистра клавиатуры.
Рисунок 2.6 Проверка состояния регистра клавиатуры
) Проверка даты производства BIOS.
Сведения об авторских правах на BIOS встроены в
ROM BIOS по адресу FE00:0. Строку с копирайтом можно легко найти в
ASCII-последовательности, а серийный номер - в виде шестнадцатеричного числа.
На экране видим семизначный номер компьютера и дата копирайт.
Рисунок 2.7 Дата производства BIOS
Дата также записана в ROM BIOS, начиная с адреса
FFFF:5. После выполнения соответствующей команды в ASCII -последовательности
будет находиться эта дата, записанная в формате мм/дд/гг.
Рисунок 2.8 Дата производства ROM BIOS
)Пример машинных кодов.
Рассмотрим создание программы на машинном языке,
ее представление в памяти и результаты выполнения. Команда отладчика A
(Assemble) переводит DEBUG в режим приема команд ассемблера и перевода их в
машинные коды.
Рисунок 2.9 ввел команду А
Теперь, когда программа введена в память,
попробуем управлять ее выполнением. Для начала проверим текущее состояние
регистров и флагов, для этого вводим команду R.
Рисунок 2.10 Проверка текущего состояния
регистров и флагов
) Команда отладчика U (Unassemble) показывает
машинные коды для команд ассемблера.
Выполнил её. Появятся инструкции, находящиеся в
указанном диапазоне, на ассемблере, в машинных кодах, а также адрес каждой
инструкции. Выполнил программу пошагово, используя команду T.
Рисунок 2.11 Ввел команду Т
Использовав во второй раз команду T, мы
выполнили инструкцию MOV. Машинный код операнда инструкции - 00D8. Операция
прибавляет AL к BL. Для выхода введем Q. И вновь дизассемблируем созданный
testpi.com.
Рисунок 2.12 Вышел из режима debug
.1 АРИФМЕТИЧЕСКИЕ КОМАНДЫ, КОМАНДЫ ПЕРЕДАЧИ
Предложения, составляющие программу, могут
представлять собой синтаксическую конструкцию, соответствующую команде,
макрокоманде,
директиве
или комментарию. Для того чтобы транслятор ассемблера мог распознать их, они
должны формироваться по определенным синтаксическим правилам. Для этого лучше
всего использовать формальное описание синтаксиса языка наподобие правил
грамматики. Наиболее распространенные способы подобного описания языка
программирования - синтаксические диаграммы и расширенные формы Бэкуса-Наура.
Для практического использования более удобны синтаксические диаграммы. К
примеру, синтаксис предложений ассемблера можно описать с помощью
синтаксических диаграмм, показанных на следующих рисунках[3].
Рисунок 2.1.1 Формат предложения ассемблера
Рисунок 2.1.2 Формат директив
Рисунок 2.1.3 Формат команд и макрокоманд
Имя метки - идентификатор, значением которого
является адрес первого байта того предложения исходного текста программы,
которое он обозначает.
Имя - идентификатор, отличающий данную директиву
от других одноименных директив. В результате обработки ассемблером определенной
директивы этому имени могут быть присвоены определенные характеристики.
Код операции (коп) и директива - это
мнемонические обозначения соответствующей машинной команды, макрокоманды или
директивы транслятора.
Операнды - части команды, макрокоманды или
директивы ассемблера, обозначающие объекты, над которыми производятся действия.
Операнды ассемблера описываются выражениями с числовыми и текстовыми
константами, метками и идентификаторами переменных с использованием знаков
операций и некоторых зарезервированных слов.
Программирование арифметических выражений в
языке Ассемблер происходит через некоторые команды такие, как: mul, div, sub,
add. Эти команды называются командами арифметических операций.- команда
умножения. Она умножает регистр ax на то, что стоит после нее. Результат
заносится в ax. - команда деления. Она делит регистр ax на то, что стоит после
нее. Результат заносится в ax. - команда сложения. Слаживает два числа.
Результат заносится в первый регистр.- команда вычитания. Вычитает два числа.
Результат заносится в первый регистр.
Команды пересылки данных делятся на команды:
ввода из порта и вывода в порт;
работы с адресами и указателями;
преобразования данных;
работы со стеком.
Пример команды “пересылка”:<операнд
назначения>,<операнд-источник> xchg <операнд!>,<операнд2>.
Команда mov не может непосредственно пересылать
из одной области памяти в другую, а только в регистр или из регистра. Если надо
обмен в памяти сделать, то меняют через регистр:
model small;
.data;db 5;db 1;
.code;;al, fls;fld,al;start.
Нельзя также пересылать из одного сегментного
регистра в другой (только через регистры общего назначения), нельзя грузить в
сегментный регистр непосредственно из памяти, нельзя посылать через mov что
либо в cs (так как это будет изменение потока программы).это то же, что mov, с
теми же ограничениями, но она просто меняет местами содержимое операндов.
В качестве примера вывод в динамик. На динамик
выводится через таймер. Каналы таймера имеют одинаковую структуру, основу
которой составляют три регистра:регистр ввода-вывода разрядностью 8 битов,
регистр-фиксатор (latch register) и регистр-счетчик (counter register), оба по
16 битов[4].
Допустимыми символами при написании текста
программ являются:
все латинские буквы: A-Z, a-z. При этом
заглавные и строчные буквы считаются эквивалентными;
цифры от 0 до 9;
знаки ?, @, $, _, &;
разделители , . [ ] ( ) < > { } + / * % !
' " ? \ = # ^.
.2 МАНИПУЛЯЦИИ НАД БИТАМИ, СТРОКОВЫЕ ОПЕРАЦИИ.
Одной из функций, в наборе команд
микропроцессора уделено особое внимание, этой функцией является обработка
строк. Строка символов или чисел, с которыми программа работает, как с группой,
является типом данных. Программа пересылает строку из одного места в другое,
сравнивает ее с другими строками, а также ищет в ней значение. Обычным типом
данных является строка символов. Программа представляет каждое слово,
предложение либо другую структуру строкой символов в памяти. Функции
редактирования, например, в большой степени используют операции поиска и
пересылки.
Строковые операции называют цепочечными или
операциями над цепочками байтов.
Строка-это цепочка байтов, для которой известен
алгоритм определения ее длины. В языках программирования прописывают процедуру
определения длины строки, а также вводят ограничение на то, какие байты могут
содержаться в строке, а также в какой кодировке должны интерпретироваться
строки- сколько байтов кодирует символ, и какая таблица будет использоваться
для сопоставления байтов и символов. В языке Си под строкой понимается
последовательность байтов, заканчивающаяся байтом со значением 0.
Строковые операции работают с одним элементом
строки: байтом, словом, двойным словом. Для того чтобы команда манипулировала
последовательностью таких элементов, используются команды-префиксы:повторять,
пока содержимое ECX не обратится в 0;/REPZ-повторять пока равно/нуль. Данный
префикс заставляет выполнять строковую команду до тех пор, пока содержимое ECX
не обратится в 0;/REPZ-повторять пока не равно/не нуль. Данный префикс
заставляет выполнять строковую команду до тех пор, пока содержимое ECX не
обратится в 0.
Строковые команды считают, что строка -источник
находится по адресу DS:ESI(для нас это просто ESI),а строка-приемник по адресу
ES:EDI. Все строковые команды можно разделить на шесть групп:
Команды пересылки:- копирование строки байтов;-
копирование строки слов;- копирование строки двойных слов.
Возможен также формат MOVS приемник, источник в
этом случае ассемблер по типу операндов сам определяет, какую из трех форм
команд
следует выбрать. Команда копирует элемент строки
из адреса, определяемого ESI, в адрес, определяемый EDI. После выполнения такой
команды содержимое ESI и EDI увеличивается (флаг DF=0) или уменьшается(флаг
DF=1) на размерах элемента строки
Команды сравнения:- сравнение строк байтов;-
сравнение строк слов;- сравнение строк двойных слов.
Команды поиска (сканирования):- сканирование
строки байтов;- сканирование строки слов;- сканирование строки двойных слов.
Команды чтения из строки- чтение байта из
строки;- чтение слова из строки;- чтение двойного слова из строки.
Возможен также формат LODS источник в этом
случае ассемблер по типу операндов сам определяет, какую из трех форм команд
следует выбрать. Команда осуществляет копирование из памяти, которая адресуется
ESI, элемента в AL,AX или EAX. После выполнения такой команды содержимое EDI
увеличивается на размер элемента строки
Команда записи в строку:- запись байта в
строку;- запись слова в строку;- запись двойного слова в строку.
Возможен также формат STOS приемник, источник в
этом случае ассемблер по типу операндов сам определяет, какую из трех форм
команд следует выбрать. Команда осуществляет копирование в память, которая
адресуется EDI, элемента из AL,AX или EAX. После выполнения такой команды
содержимое EDI увеличивается на размер элемента строки
. ПРОГРАММИРОВАНИЕ С ИСПОЛЬЗОВАНИЕМ MASM
.1 ПАКЕТ MASM. СТРУКТУРА ПРОГРАММЫ
Assembler (MASM) - ассемблер для процессоров
семейства x86. Первоначально был произведён компанией Microsoft для написания
программ в операционной системе MS-DOS и был в течение некоторого времени самым
популярным ассемблером, доступным для неё. Это поддерживало широкое
разнообразие макросредств и структурированность программных идиом, включая
конструкции высокого уровня для повторов, вызовов процедур и чередований
(поэтому MASM - ассемблер высокого уровня). Позднее была добавлена возможность
написания программ для Windows. MASM - один из немногих инструментов разработки
Microsoft, для которых не было отдельных 16- и 32-битных версий.-
специализированный пакет программирования на языке ассемблера IA-32. Являясь
продуктом фирмы Microsoft, он максимально
приспособлен
для создания Windows-приложений на ассемблере. Кроме транслятора, компоновщика
и необходимых библиотек пакет Masm32 включает сравнительно простой текстовый
редактор и некоторые инструменты, предназначенные для облегчения
программирования на ассемблере.
Программа, написанная на ассемблере MASM, может
состоять из нескольких частей, называемых модулями, в каждом из которых могут
быть определены один или несколько сегментов данных, стека и кода. Любая
законченная программа на ассемблере должна включать один главный, или основной
(main), модуль, с которого начинается ее выполнение. Основной модуль может
содержать программные сегменты, сегменты данных и стека, объявленные при помощи
упрощенных директив. Кроме того, перед объявлением сегментов нужно указать
модель памяти при помощи директивы .MODEL.
.2 СОВМЕСТНОЕ ИСПОЛЬЗОВАНИЕ ЯЗЫКА АССЕМБЛЕР С
ДРУГИМИ ЯЗЫКАМИ ПРОГРАММИРОВАНИЯ
Когда приложение разрабатывается для встроенной
системы, могут возникать ситуации, в которых будет необходимость написать части
кода на ассемблере, например, при использовании механизмов в микроконтроллере
AVR, которые требуют точного выбора времени и специальных последовательностей
команды[4].
Совмещение C и ассемблера. AVR IAR C / C ++
Компилятор обеспечивает несколько способов совмещения C или C++ и ассемблера:
модули, написанные полностью на ассемблере;
встроенные функции (альтернатива c);
встроенный ассемблер.
Компилятор обеспечивает малое число предопределенных
функций, позволяющих прямой доступ к низкоуровневым процессорным инструкциям,
без необходимости использовать язык ассемблера. Эти функции известны как
встроенные функции. Они могут быть очень полезны, например, при
время-критических подпрограммах.
Встроенная функция напоминает нормальный
функциональный запрос, но это - действительно встроенная функция, которую
распознает компилятор. Встроенные функции компилируются в линейное кодирование,
как отдельная команда, или как короткая последовательность команд.
Преимущество встроенной функции в сравнении с
использованием встроенного ассемблера состоит в том, что компилятор имеет всю
необходимую информацию, чтобы связать с помощью интерфейса последовательность
должным образом с регистром размещения и переменных. Компилятор также знает,
как оптимизировать функции с таким последовательностями; кое-что компилятор не
может делать со встроенными последовательностями ассемблера.
Можно написать части вашего приложения на
ассемблере и совместить их с C или C++ модулями. Это выгодно по нескольким
причинам:
хорошо определенный функциональный механизм
запроса
код будет просто читать
оптимизатор может работать с функциями C или C
++.
Есть возможность вставлять код ассемблера
непосредственно в функцию C или C ++. Ключевое слово ассемблера транслирует и
вставляет инструкцию или инструкции ассемблера.
Встроенная команда ассемблера будет просто
вставлена в данном местоположении в потоке программы. Последствия или побочные
эффекты, которые вставка может иметь на окружающем коде, не будут учтены. Если,
например, регистраторы или местоположения памяти изменятся, их, вероятно,
придется восстанавливать в пределах последовательности встроенных команд
ассемблера для остальной части кода, чтобы работать должным образом[5].
Встроенные последовательности ассемблера не
имеют никакого четкого интерфейса с окружающим кодом, сгенерированным от вашего
C или кода C++. Это делает встроенный ассемблерный код хрупким, и возможно
также станет проблемой обслуживания, если вы модернизируете код в будущем.
Кроме того, имеются несколько ограничений к использованию встроенного
ассемблера:
различные оптимизации компилятора игнорируют
любые эффекты
встроенных последовательностей, которые не будут
оптимизированы вообще в общем, директивы ассемблера вызовут ошибки или не будут
иметь никакого значения. директивы же определения данных будут работать, как
ожидается к авто переменным (регистры) нельзя обращаться.
Встроенный ассемблер - поэтому лучше всего
избегать. Если не имеется никакой подходящей доступной встроенной функции,
рекомендуется использование модулей, написанных на языке ассемблеров вместо
встроенного ассемблера, потому что функциональный запрос к подпрограмме
ассемблера обычно занимает меньше работы.
.3 КОМАНДЫ УПРАВЛЕНИЯ ЦИКЛАМИ. КОМАНДЫ РАБОТЫ СО
СТРОКАМИ. ВЫВОД НА ЭКРАН В ТЕКСТОВОМ РЕЖИМЕ
Существует несколько команд условного перехода,
предназначенных для управления циклами в программах. Поскольку программые циклы
используются часто, желательно эффективное управление циклом.
Так же, как строковые команды используют регистр
CX в качестве счетчика, команды цикла LOOP используют регистр CX в качестве
счетчика цикла. Все эти команды неявно рассматривают регистр CX как счетчик
итераций цикла. Простейшая команда среди них - команда LOOP. Команда LOOP
уменьшает регистр CX и передает управление на метку, если содержимое регистра
CX не равно 0. Если вычитание единицы из регистра CX не привело к нулевому
результату, команда LOOP не делает перехода, и выполняется следующая
команда[6].
Программа помещает число итераций цикла в
регистр CX перед выполнением цикла. Затем выполняется тело цикла, а следом за
ним команда LOOP. Она уменьшает счетчик на единицу, что соответствует
единственной, только что выполненной итерации цикла. Если теперь счетчик в
регистре CX равен 0, программа продолжает выполняться после команды LOOP. Если
счетчик не равен 0, управление возвращается к началу цикла, чтобы совершить еще
один проход по телу цикла. Тело цикла выполняется столько раз, сколько было
сначала задано содержимым регистра CX. Единственное важное замечание: если
программа внутри цикла изменяет регистр CX, число итераций цикла не будет
соответствовать начальному значению в регистре CX.
Описанный метод одинаково хорошо работает, когда
число циклов известно во время ассемблирования (как в примере, где LOOP_COUNT -
непосредственно заносимое значение), и когда число циклов определяется во
время выполнения. Если вычисленное число
оказалось равным 0, цикл выполнится 65536 раз. Когда микропроцессор 8088
выполняет первую команду LOOP, он уменьшает CX от 0 до 0FFFFH, и поскольку
теперь регистр CX ненулевой, повторяет цикл. Таким образом, загрузка нулевого
значения счетчика циклов - специальный случай. Этот специальный случай
обрабатывается командой JCXZ (переход, если содержимое регистра CX равно 0).
Эта команда проверяет текущее содержимое регистра CX, и делает переход, если
оно равно нулю. Команда не проверяет ни одного флага, и не влияет ни на один из
них. Следующий пример аналогичен предыдущему, за исключением того, что он загружает
регистр CX из ячейки памяти, содержимое которой вычисляется во время выполнения
программы. По этой причине может оказаться, что счетчик циклов нулевой, и
пример использует команду JCXZ, чтобы проверить, нужно ли полностью пропустить
тело цикла[7].
В программе не нужно использовать команду JCXZ в
каждом цикле с вычисляемым счетчиком. Если программист знает, что счетчик
циклов никогда не будет равен нулю, проверка не нужна. Однако опыт показывает,
что значение, которое "никогда" не должно появиться, обычно
появляется в первую очередь, как только вы начинаете выполнять программу.
Оставшиеся две команды цикла предоставляют еще
большие возможностей при управлении циклами. Эти команды аналогичны префиксам
REPE и REPNE. Если команда LOOP выходит из цикла, только когда в регистре CX
оказывается нуль, то команда LOOPE (цикл, пока равно) выходит из цикла, если
установлен флаг нуля, или если в регистре CX получился 0. Тем самым становится
возможным двойственное завершение цикла. Программа может загрузить в регистр CX
максимальное число итераций цикла, а затем проверять флаг нуля в конце каждого
цикла на условие завершения. Команда LOOPNE (цикл, пока не равно) выполняет
обратную к описанной проверку флага нуля: цикл здесь завершается, если регистр
достиг нуля, или если установлен флаг нуля. Следующий пример показывает
использование команды LOOPNE. В примере складываются два списка чисел, чтобы
найти пару элементов, сумма которых точно равна 100. Так как в каждой итерации
перед проверкой складываются два чила, команду REPNE CMPSB использовать нельзя.
Команды работы со строками работают с большими
структурами данных в памяти, такими, как алфавитно-цифровые строки символов.
Смотри также раздел, посвященный Вводу/Выводу, для получения более подробной
информации относительно команд Ввода/Вывода строк (иногда их называют блочными
командами Ввода/Вывода).
Работа со строками может выполняться посредством
команд работы со строками (которые выполняют только одну итерацию для каждой
операции) совместно с другими возможностями команд процессора, такими, как
префиксы повторения. Команды работы со строками:- Переслать строку;- Сравнить
строки;- Сканировать строку; - Загрузить строку; - Запомнить строку.
После выполнения команды работы со строкой,
регистры строки-источника и строки-приемника указывают на следующие элементы в
этих строках. Эти регистры автоматически увеличивают или уменьшают свои
значения на количество байт, занятых каждым элементом строки. Элементом строки
может быть байт, слово или двойное слово.
Операции работы со строками могут начинаться со
старших адресов и выполняться по направлению к младшим адресам, или могут
начинаться с младших адресов и выполняться по направлению к старшим адресам.
Исключения и прерывания, которые могут возникать
в процессе выполнения команд работы со строками, сохраняют регистры в таком
состоянии, чтобы команда работы со строкой могла быть повторена. Регистры
источника и приемника указывают на следующие элементы строк, регистр EIP
указывает на команду работы со строкой и регистр ECX содержит значение,
сохраненное в нем со времени последней успешной итерации. Все, что необходимо
для повторного запуска операции - это обработать прерывание или зафиксировать
источник исключения, затем выполнить команду IRET.
Префиксы повторения REP (Повторять, пока ECX не
равен нулю), REPE/REPZ (Повторять пока равно/ноль) и REPNE/REPNZ (Повторять
пока не равно/не ноль) задают повторяющееся выполнение команд работы со
строками. Эта форма итераций позволяет операциям работы со строками работать
быстрее, чем это возможно при организации программных циклов.
Когда у команды работы со строкой имеется
префикс повторения, операция выполняется до тех пор, пока одно из условий
окончания, определяемое префиксом, не будет выполнено.
Префиксы повторения отличаются друг от друга по
своим дополнительным условиям окончания работы. Префикс REP не имеет
дополнительных условий окончания. Префиксы REPE/REPZ и REPNE/REPNZ используются
исключительно с командами SCAS (Сканировать строку) и CMPS (Сравнить строки).
Префикс REPE/REPZ заканчивает работу, если флаг ZF очищен. Префикс REPNE/REPNZ
заканчивает работу, если флаг ZF установлен. Флаг ZF не требует предварительной
инициализации перед выполнением повторяющихся команд работы со строками, так
как и SCAS и CMPS воздействуют на флаг ZF в соответствие с результатами
сравнения, которое они выполнили.
Хотя регистры общего назначения в большинстве
случаев полностью взаимозаменяемы, команды работы со строками требуют
использования двух
специальных регистров. Строки источника и
приемника находятся в памяти, адресуемой регистрами ESI и EDI. Регистр ESI
указывает на операнд-источник. По умолчанию, регистр ESI используется вместе с
сегментным регистром DS. Префикс замены сегмента позволяет использовать регистр
ESI вместе с сегментными регистрами CS, SS, ES, FS или GS. Регистр EDI
указывает на операнд назначения. Он использует сегмент, на который который
указывает сегментный регистр ES; замена этого сегмента запрещена. Использование
двух различных сегментных регистров в одной команде позволяет работать со
строками, расположенными в различных сегментах.
Когда в командах работы со строками используются
регистры ESI и EDI, они автоматически увеличиваются или уменьшаются после
каждой итерации. Действия над строками можно начинать выполнять со старших
адресов по направлению к младшим адресам, или они могут выполняться, начиная с
младших адресов по направлению к старшим адресам.
Направление операций управляется флагом DF. Если
флаг очищен, значения регистров увеличиваются. Если флаг установлен, значения
регистров уменьшаются. Команды STD и CLD устанавливают и очищают этот
флаг.(Переслать строку) перемещает элемент строки, адресуемый регистром ESI в
позицию, адрес которой указан в регистре EDI. Команда MOVEB перемещает байты,
команда MOVEW перемещает слова и команда MOVED перемещает двойные слова.
Команда MOVE, когда она дополнена префиксом REP, работает как пересылка блоков
из памяти в память. Для выполнения этой операции программа должна
инициализировать регистры ECX, ESI и EDI. Регистр ECX указывает количество
элементов в блоке.(Сравнение строк) вычитает элемент строки-приемника из
элемента строки-источника и обновляет флаги AF, SF, PF, CF и OF. Ни один из
элементов не будет записан обратно в память. Если элементы строки равны,
устанавливается флаг ZF; в противном случае этот флаг очищается. CMPSB
сравнивает байты, CMPSW сравнивает слова и CMPSD сравнивает двойные слова.(Сканировать
строку) вычитает элемент строки-приемника из регистра EAX, AX или AL (в
зависимости от длины операнда) и обновляет флаги AF, SF, ZF, PF и OF. Строка и
регистры не изменяются. Если значения равны, устанавливается флаг ZF; в
противном случае флаг очищается. Команда SCASB сканирует байты, команда SCASW
сканирует слова и команда SCASD сканирует двойные слова. Когда префиксы
REPE/REPZ или REPNE/REPNZ модифицируют команду SCAS или CMPS, сформированный
при этом цикл заканчивается либо по счетчику цикла, либо по тому воздействию,
которое команды SCAS или CMPS оказывают на флаг ZF. (Загрузить строку) помещает
элемент строки-источника, на который указывает адрес в регистре ESI, в регистр
EAX для строк из двойных слов, в регистр AX для строк из слов или в регистр AL
для строк из байтов. Эта команда используется обычно внутри цикла, где другие
команды обрабатывают каждый элемент строки по мере его появления в регистре.
STOS (Запомнить строку) помещает элемент строки из регистра EAX, AX или AL в
строку, на которую указывает адрес в регистре EDI. Эта команда обычно
используется в цикле, где она записывает в память результат обработки элемента
строки, считанного из памяти при помощи команды LODS. Команда REP'STOS является
самым быстрым способом инициализации большого блока памяти[9].
Для вывода данных на экран можно использовать
два вида функций: универсальную функцию 40h (вывод в файл) и группу
специализированных функций MS DOS вывода на экран.
Вывод символа на экран (02h int 21h). Функция
02h позволяет вывести один символ на экран.
Вход: АН >> 02h - вывод символа;= символ
для вывода.
Функция 02h проверяет наличие в клавиатурном
буфере символов нажатия комбинации CTRL + C (CTRL + Break), при обнаружении
которых производится вызов прерывания int 23h. В процессе вывода функция
реагирует на управляющие символы, такие как 0dh (возврат каретки), 0ah (перевод
строки), 08h (курсор назад на один символ), 07h (звуковой сигнал) и т. д.
Прямой вывод символа на экран (06h int 21h).
Функция 06h выводит один символ на экран. Эта
функция универсальна, так как используется и для ввода и для вывода символа.
Вход: АН = 06h - вывод символа на экран;= символ
для вывода (за исключением 0ffn).
Функция 06h не проверяет наличие в буфере
символов нажатия комбинации CTRL + C (CTRL + Break). Порядок использования
данной функции аналогичен порядку использования функции 02h.
Вывод строки на экран (09h int 21h)
Функция 09h выводит строку символов на экран.
Строка должна обязательно заканчиваться символом $. Данную функцию удобно
использовать для вывода на экран различных диагностических сообщений. Если
требуется организовать вывод строк, длина которых формируется динамически, то
лучше либо использовать упомянутую выше функцию 40h, либо выводить их в цикле,
тело которого содержит одну из функций 02h или 06h.
Вход: АН = 09h - вывод строки на экран;: DX -
адрес строки для вывода с завершающим символом $.
Функция 09h проверяет наличие в клавиатурном
буфере символов нажатия комбинации CTRL + C (CTRL + Break), при обнаружении
которых производится вызов прерывания int 23h. В процессе вывода функция
реагирует на управляющие символы, такие как 0dh (возврат каретки), 0ah (перевод
строки), 08h (курсор назад на один символ), 07h (звуковой сигнал) и т. д.
ЗАКЛЮЧЕНИЕ
Практика «Основы микропроцессорной техники» предоставила
возможность самостоятельной работы над пройденными темами по предмету «Основы
микропроцессорной техники». Практика предусматривает закрепление основ цифровой
техники, ее схемотехники, особенностей анализа комбинационных и
последовательных устройств, существующих и перспективных семейств
микропроцессоров и микроконтроллеров.
Во время практики было произведено повторение
основных узлов и устройств, входящих в элементную базу микропроцессорной
техники. Было изучено, строительство функциональных схем узлов. Так же я
научился определять классификацию и функциональные возможности триггеров,
регистров, счетчиков и получил представление о принципах программирования на
машинном уровне на примере языка ассемблер
ЛИТЕРАТУРА
А.Г.Алексенко,
И.И.Шагурин. Микросхемотехника.-М.: Радио и связь, 1982-415с.
Гуров
В.В., Рыбаков А.А. Лабораторный практикум "Разработка микропроцессорных
систем на основе однокристальных микроконтроллеров". - М.: МИФИ, 2000.
Информационно-аналитические
материалы Центра Информационных Технологий, 1996.
Преснухин
Л.Н. Микропроцессоры.
Гивоне
Д., Россер Р. Микропроцессоры и микрокомпьютеры.
Пузанков
Д.В. Микропроцессорные системы.
Микропроцессорные
устройства систем управления Автор: Иванов Ю.И., Югай В.Л.
Основы
микропроцессорной техники Новиков Ю.В. , Скоробогатов П.К.
Л.М.
Гольденберг. Цифровые устройства и микропроцессорные системы.