ПОЛЕЗНОСТЬ
.docРаспределение памяти (ПЗУ. ОЗУ)
При написании программы на ассемблере в текст включают директивы. Это указания программе ассемблеру о размещении исполняемого (объектного) кода в ПЗУ микроконтроллера, резервировании памяти и присвоения константам значений.
• END. Этой директивой заканчивается транслируемая часть текста. После неё можно писать в файле текста всё, что угодно. Написанные ниже команды не будут переводиться в машинные коды.
• ORG address. Директива указывает ассемблеру с какого адреса размещать код следующей за ней команды в ПЗУ.
• имя EQU значение. Позволяет присвоить константе значение (число), которое будет заменять имя константы при трансляции. Изменив значение один раз в модуле программы, содержащем определения EQU, после трансляции получим новые константы во всех командах, где присутствует имя константы.
Директивы резервирования памяти (в ПЗУ) • DB значение. Директива позволяет записать в последовательные ячейки ПЗУ коды, расположенные в поле значение через запятую. В апострофах можно располагать символы ASCII группой без запятых. • DW значение. Директива позволяет записать в последовательные ячейки ПЗУ 16-ти разрядные коды (слова), расположенные в поле значение через запятую.
Директивы подстановок
В ассемблере могут использоваться подстановки, которые являются очень удобным средством программирования. При помощи директив подстановок программист создает поименованные объекты, которые могут быть использованы в тех или иных местах исходного текста.
Директива
резервирования памяти (в ОЗУ).
•
имя: DS значение.
Совместно с директивой ORG позволяет
определить адрес ячейки (значение) для
имени, указанного в поле метки этой
директивы. Для одного имени могут быть
зарезервированы несколько ячеек, то
есть созданы области под массивы данных.
Используя директивы DS, можем в программе
подставлять не прямые адреса ячеек ОЗУ,
а указанные в директиве смысловые имена.
В области памяти с прямой битовой
адресацией (20h…2Fh) можно дать имена
отдельным битам – программным флагам.
Пример из реальной программы,
содержащий подстановки, резервирование
ячеек и создание смысловых флагов
приведен ниже:
Макросы
Макросы. Макросом является последовательность строк исходного кода, которая будет подставляться вместо одной исходной строки. Прежде чем макрос сможет быть использован, его надо определить при помощи составной директивы сложной текстовой подстановки
имя: .MACRO аргументы ;текст подстановки .ENDM
Синонимом закрывающей строки для сложной текстовой подстановки является MACEND. В списке аргументов не допускается использовать пробелы, разделителем аргументов является запятая. Отсутствие аргументов объявляется одиночной запятой.
Транслятор хранит определение Макроса и вставляет ее вместо того оператора исходного текста, в мнемокоде которого записано имя Макроса. Операнды замещаемого оператора подставляются в текст подстановки вместо аргументов, заданных в определении Макроса. Указанные в макроопределении аргументы являются его формальными параметрами. При выполнении подстановки формальные параметры заменяются на фактические значения, содержащиеся в операндах вызова сложной текстовой подстановки. После выполнения подстановки производится трансляция подставленного текста в машинный код. Использование Макросов повышает производительность труда программиста, уменьшает объем текста программы, делает текст более «читаемым» с точки зрения смысла реализуемого алгоритма.
К сожалению, используемый для демонстрации работы микроконтроллера программный симулятор не позволяет ассемблировать программы с директивами EQU, DS и Macro. Директивы ORG, END, DB и DW работают.
Сложение можно выполнить без учёта переноса (ADD) или с учётом переноса (ADDC). Перенос складывается с младшим разрядом суммы, получившейся в Аккумуляторе. Наличие учёта переноса позволяет выполнять арифметические действия с многобайтными числами или накапливать многобайтные результаты при сложении нескольких байтовых операндов. Рассмотрим пример: в ячейках 31h, 30h накапливается двухбайтовая сумма чисел, поступающая из порта Р1. Поскольку, даже при сложении двух байтовых чисел (например, 100 и 200) результат может превысить число 255 и не поместиться в один байт, в старшем байте суммы нужно учитывать возникшие при сложении младших байт переносы в старший разряд. Программа сложения выглядит следующим образом:
Таким образом, в старшем байте копятся только переносы. Этот принцип можно распространить на большее число байт, Так, при сложении двух двухбайтовых чисел, результат должен накапливаться уже в трёх ячейках памяти.
Следует запомнить, что команды INC и DEC не влияют на флаг переноса С. То есть при переходе операнда под воздействием команды INC от кода FFh к коду 00h (переполнении) установки бита С в единицу не произойдёт. Аналогично для перехода 00h – FFh при выполнении команды DEC.
Вычитание всегда выполняется с учётом переноса. То есть при первом вычитании (младших байт) бит переноса «С» должен быть сброшен в Ноль, чтобы не появилась ошибка на единицу в младшем разряде разности. Напомню, что бит переноса устанавливается по результату предыдущей арифметической или логической операции. Поскольку учет переноса есть, можно выполнять вычитание многобайтовых чисел.
Рассмотрим пример двухбайтового вычитания. Вы, наверное, заметили, что отсутствует команда уменьшения указателя DPTR на единицу. Попробуем реализовать эту операцию последовательностью команд, памятуя, что 16-ти разрядный регистр DPTR физически состоит из двух 8-ми разрядных прямо адресуемых ячеек DPH (High, старшая) и DPL (Low младшая).
Команда NOP (no operation) не выполняет никаких действий. Выполняется за один машинный цикл и может использоваться для создания программных задержек.
Система условных переходов предоставляет возможность осуществлять ветвление по следующим условиям: аккумулятор содержит нуль (JZ), содержимое аккумулятора не равно нулю (JNZ), перенос равен единице (JC), перенос равен нулю (JNC), адресуемый бит равен единице (JB), адресуемый бит равен нулю (JNB). Все условные переходы – относительные. Короткий относительный переход позволяет передать управление в пределах от – 128 до +127 байт относительно адреса следующей команды (команды, следующей по порядку за командой относительного перехода). В случае, если метка перехода находится за пределами «относительной» страницы в ПЗУ, следует использовать комбинацию команд относительного и абсолютного перехода.
Для организации программных циклов удобно пользоваться командой DJNZ. В качестве счётчика циклов может использоваться не только регистр, но и прямо адресуемый байт (например, ячейка резидентной памяти данных). Команда CJNE эффективно используется в процедурах ожидания какого-либо события. Например, команда
WAIT: CJNE A,P0 WAIT
будет выполняться до тех пор, пока на линиях порта 0 не установится информация, совпадающая с содержимым аккумулятора.
Все команды данной группы, за исключением CJNE и JBC, не оказывают воздействия на флаги регистра PSW. Команда CJNE устанавливает флаг C, если первый операнд оказывается меньше второго. Поэтому CJNE может использоваться в качестве «сравнения без разрушения» в отличие от вычитания, когда первый операнд в аккумуляторе заменяется на разность.
Команда JBC сбрасывает флаг C в случае перехода.
-
