- •Некоторые понятия языка Ассемблер
- •Поля ассемблерной строки
- •Директивы ассемблера
- •Директива end.
- •2.2 Директива org (начало, origin).
- •Директива equ (equal, приравнять, присвоить)
- •Директива set (установить).
- •Директива db (определить байт, define)
- •Директива dw (определить слово)
- •2.7. Директива ds (define spice, определить память)
В ведение
Программное обеспечение (ПО) является частью микроЭВМ, без которого ее функционирование невозможно.
В понятие программного обеспечения входит язык программирования и наборы программ, разрабатываемых или используемых пользователем при разработке микроЭВМ.
В современных микропроцессорных системах в качестве языков программирования используются языки высокого уровня (ЯВУ), такие как Паскаль, Бейсик, СИ и т.п. Они гарантируют сокращение времени и упрощение процедуры разработки. Однако, наряду с ними в практике эффективно применяется и т.н. Ассемблер – язык низшего уровня, который оперирует не с операторами как в ЯВУ, а непосредственно с машинными командами из системы команд данного микропроцессора. Это обеспечивает два преимущества, а именно
уменьшение объёма программы на фоне сокращения времени её исполнения;
возможность организации более “тонкого” взаимодействия между микро ЭВМ и управляемым, особенно динамическим, объектом.
Ниже излагаются некоторые правила, которые необходимо соблюдать при разработке программ на ассемблере Аsm85. Этот Ассемблер хорошо адаптирован к учебному процессу – русифицирован, имеет достаточные функциональные возможности, хорошо взаимодействует с моделирующим отладчиком SIM85. Материал, изложенный ниже предназначен для теоретической подготовки и выполнения лабораторных работ по дисциплинам ОМПТ, МИУС ( специальности АТ, АС, АТК, АР и др.).
Некоторые понятия языка Ассемблер
Различают два термина “ Ассемблер ”, а именно
символический язык, используемый при разработке программ, обеспечивающих функционирование микропроцессорных систем;
средство преобразования лингвистических предложений языка Ассемблер в двоичные коды машинного языка, воспринимаемого микропроцессором непосредственно и управляющего его функционированием.
Ниже рассматривается Ассемблер, как символический язык.
Ассемблер относится к типу формализованных языков. Нарушение формальных правил приведёт к ошибке при компиляции или (что хуже) к ошибке при исполнении программы.
В рамках формальных правил (требований), ассемблерные программы записываются в виде последовательности команд, называемых также ассемблерными строками, а равно предложениями или операторами. В отличии от ЯВУ каждый оператор (строка или предложение) ассемблера порождает только одну машинную команду.
Так записанная программа состоит из предложений, а предложение – из полей, часть из которых заполняется обязательно, а часть – нет.
-
Ассемблерное предложение имеет следующую структуру:
Метка
Код
Операнд
Комментарий
[Метка: ]
КОп
[Операнд1[,Операнд2]]
[;Комментарий]
Вторая строка поясняет структуру ассемблерного предложения, а первая, строка, в которой содержаться заголовки полей, в предложении не записывается.
Элементы, содержащиеся в квадратных скобках, не являются обязательными в предложении.
Для разделения полей можно использовать пробелы или табуляции.
Д аже если в предложении отсутствует метка, то код в предложении отделяется от левого края листа знаком табуляции. Нижеприведенный фрагмент профессионального листинга программы с условным обозначением “ У810”, поясняет перечисленные требования.
Поля ассемблерной строки
1.1.1. Поле комментария. Одним из практических требований к ассемблер – программе, является самокомментируемость. Такое требование выполняется двояким образом, а именно
программа ( фрагмент программы) должны содержать строки или поля комментариев;
комментарии должны передавать назначение и действие оператора во взаимосвязи с остальной частью программы, а не его действие, определяемое мнемоникой команды и, поэтому, понятное из неё и без комментария.
Комментарии могут быть, как на целую строку, так и внутри строковые.
C помощью комментариев на целую строку, строится заголовок программы или разделяются отдельные фрагменты программного кода.
Заголовок, как правило, должен содержать:
название или обозначение программы или её фрагмента;
место расположения операторов и результата;
используемые ресурсы;
требования при исполнении и отладке;
характеристики (длину, время исполнения и т.п.) программы или её фрагмента и т.п.
Разделяя фрагменты программы комментариями, можно пояснить структуру программы и (или) назначение фрагмента.
Комментарии в строке завершают предложение и поясняют назначение символьных обозначений приведённые в нем.
Все комментарии начинаются с символа “ ; ” , поэтому не преобразуются ассемблером в машинную команду, а включаются в протокол компиляции (листинг) как текст.
Комментарии при этом должны быть краткими, чёткими, можно использовать повелительное наклонение и выносить вперёд ключевые слова.
1.1.2 Поле метки. Необязательное символическое наименование в поле метки ассоциируется с 16-битным адресом той ячейки памяти, в которую будет размещён первый байт отмеченной команды.
Метки используются в качестве адресов перехода для команд передачи управления. Они освобождают программиста от необходимости оперировать абсолютными адресами памяти. К командам, использующим метки в качестве адресов, относятся, например, команды JMP addr; Jcond addr; CALL addr; Ccond addr. К синтаксису меток предъявляются следующие требования.
Метка имеет длину от одного до пяти или шести символов, первым из которых обязательно должна быть буква. Метка не должна содержать знаков пунктуации и пробелов. За последним символом метки следует двоеточие. В качестве меток не допускается использовать ключевые слова.
Примеры допустимых меток:, AGAIN:, CYKL:, DONE:, C5FA:, Ml:.
Следующие метки недопустимы:
8АВС — начинается не с буквы;
DONE — не заканчивается двоеточием;
SP — использовано ключевое слово;
A ONE — содержит пробел.
Метка |
Код |
Операнд |
Комментарий |
; Пример использования меток. |
|||
|
JMP |
M1 |
; переход к метке М1 |
|
* * * |
|
|
|
CALL |
DIV8 |
; вызов ; подпрограммы ; DIV8 |
|
* * * |
|
|
М1: |
MOV |
A, B |
; продолжить после ; перехода от JMP |
|
* * * |
|
При использовании меток необходимо придерживаться следующих правил.
Первое. Поскольку метки ассоциируются с адресами памяти, их нельзя дублировать в поле метки. В противном случае ассемблер – компилятор выдаёт диагностическое сообщение о многократно определённой метке.
Пример программы с ошибкой. |
|||
Метка |
Код |
Операнд |
Комментарий |
;Пример программы с ошибкой, из-за повторяющихся меток |
|||
|
JMP |
M1 |
; переход к метке М1 |
|
* * * |
|
|
|
CALL |
DIV8 |
; вызов подпрограммы ; DIV8 |
|
* * * |
|
|
М1: |
MOV |
A, B |
;продолжить после ; перехода от JMP |
|
* * * |
|
|
M1: |
LXI |
SP, BC14h |
;ошибка из-за ;повторяющейся метки |
Второе. Допускается вводить для одного оператора несколько меток.
Пример.
Метка |
Код |
Операнд |
Комментарий |
||
;Пример программы с двумя операторными метками: |
|||||
LOOP1: |
|
|
|
||
LOOP2: |
RAL |
|
|
||
|
* * * |
|
|||
|
JMP |
LOOP1 |
; повторить сдвиг |
||
|
* * * |
|
|||
|
JNZ |
LOOP2 |
; повторить, если не ;ноль |
||
|
* * * |
|
Команды JMP и JNZ передают управление (первая безусловно, вторая — при Z = 0) одной и той же ячейке памяти с командой RAL. Меткам LOOP1 и LOOP2 ассемблер присвоит одинаковые числовые значения.
Третье. Любой символический адрес, использованный в поле операнда должен один раз появиться в поле метки некоторого оператора. В противном случае, программа–ассемблер выдаёт сообщение о неопределённой метке.
Четвёртое. Каждой метке в поле метки должна соответствовать символический адрес в поле операнда хотя бы одной команды. В противном случае, программа–ассемблер выдаёт сообщение о неопределённой метке.
Пятое. Учитывая требование самокомментируемости, желательно, чтобы метки носили содержательный характер: CYСL:, SHIFT: и т.п.
1.1.3 Поле мнемоники (кода). В поле мнемоники содержится символическое описание выполняемой команды, которое заменяет в языке числовое значение (машинный код) кода операции. Большинство мнемоник представляют собой аббревиатуры предложений, характеризующих основные функции команд, например:
MOV (MOVe) — передать, переслать;
ACI (Add with Carry Immediate) —сложение с переносом непосредственное;
JNZ (Jump if Non Zero) — перейти, если не нуль;
XCHG (eXCHanGe)—обменять.
По некоторым мнемоникам можно явно определить функцию команды. Например, по мнемонике PCHL можно " опознать " передачу содержимого регистров (Н, L) в программный счётчик PC, а по мнемонике PUSH, то, что команда выполняет загрузку в стек.
Между полем мнемоники и соседним справа полем операнда необходим минимум один пробел. Мнемоники кодов операций являются ключевыми словами ассемблера и, если содержимое этого поля ошибочно не входит в множество допустимых мнемоник, ассемблер выдаёт сообщение о недействительной команде.
1.1.4 Поле операнда. В наиболее сложном поле операнда определяются данные, являющиеся операндом (операндами) команды. Следовательно, содержимое поля операнда должно интерпретироваться в соответствии с функцией команды. В качестве операндов в предложении могут фигурировать
адреса памяти;
внутренние регистры микропроцессора;
адреса портов ввода и вывода;
числовые и символьные константы.
В зависимости от функции команды, в поле операнда может содержаться один или два операнда. Следует также иметь ввиду, что операнд может задаваться с помощью выражений, вычисляемых при компиляции.
Некоторые команды, оперирующие определёнными внутренними регистрами, имеют пустое поле операнда.
Пример. |
|
||||
Метка |
Код |
Операнд |
Комментарий |
||
;Пример кодов команды с “пустым ” полем операторов: |
|
||||
|
CMA |
|
; инвертировать ; аккумулятор |
|
|
|
* * * |
|
|
||
|
RAL |
|
; сдвинуть содержимое ; через бит переноса |
|
Если в поле операнда есть данные, программа-ассемблер (компилятор) должна найти двоичный эквивалент содержимого поля операнда и подставить его (в зависимости от типа команды) в определённые биты кода операции, во второй байт 2-байтных команд или во второй и третий байты 3-байтных команд.
Вычисленное двоичное значение содержимого поля операнда должно укладываться в диапазон чисел, определяемый содержанием команды. В противном случае фиксируется недействительное поле операнда.
Поле операнда может содержать информацию следующих типов:
числа, представленные в той или иной системе счисления;
символьные константы;
внутренние регистры и регистровые пары;
символические имена.
Ниже рассматриваются способы определения информации указанных типов.
Данные и адреса памяти в виде шестнадцатеричных чисел. Содержащееся в поле операнда шестнадцатеричное число должно начинаться с цифр 0—9 и завершаться буквой Н или h (Hex). Число, начинающееся с букв А÷F, заменяющих цифры, дополняется слева незначащим нулём. Разрядность используемых чисел должна соответствовать формату операндов, с которыми оперирует команда.
Пример . |
||||
Метка |
Код |
Операнд |
Комментарий |
|
; Пример программы с операндами в шестнадцатеричной ; системе счисления. Ошибка формата операнда CPI |
||||
STORE: |
STA |
1000h |
; сохранить в ; ячейке 1000h |
|
|
MVI |
C, 0BBh |
; загрузить в С ;число 10111011b |
|
|
* * * |
|
||
COMP: |
CPI |
125h |
;недопустимый операнд ;из-за превышения ;разрядности |
|
|
* * * |
|
Данные и адреса памяти в виде десятичных чисел. Десятичное число в поле операнда заканчивается необязательной буквой d или D (Decimal). Число без буквы, но состоящее из десятичных цифр воспринимается ассемблером по умолчанию как десятичное.
Примеры задания десятичных чисел:
Метка |
Код |
Операнд |
Комментарий |
|
|||
; Пример программы с операндами в десятичной системе ; счисления |
|||||||
STORE: |
STA |
2000 |
; сохранить в ; ячейке 2000D |
||||
|
MVI |
C, 15 |
; загрузить в С ;число 00001111b |
||||
|
* * * |
|
|||||
|
ADI |
1D |
; инкрементировать ; аккумулятор; ;установить признаки |
||||
|
* * * |
|
Данные и адреса памяти в виде двоичных чисел. Двоичное число в поле операнда должно заканчиваться буквой B или b (binary).
Примеры задания операндов в виде двоичных чисел: |
|||||
Метка |
Код |
Операнд |
Комментарий |
||
; Пример программы с операндами в двоичной системе ; счисления |
|||||
|
OUT |
01b |
; вывод в первый ; порт |
||
|
XRI |
10000000b |
; инвертировать знак |
||
|
* * * |
|
|||
|
ANI |
10111111b |
; шестой бит в 0 |
||
|
* * * |
|
Символьные константы. В поле операнда допускается использовать символы внешнего алфавита, заключая их в апострофы. Программа подставляет вместо такого операнда соответствующий двоичный ASCII–код символа:
Пример. |
||||
Метка |
Код |
Операнд |
Комментарий |
|
;пример символьной константы в поле операнда |
||||
|
MVI |
А, ‘T’ |
; Передача ASCII кода ; символа ‘T’ ; в аккумулятор ADD |
|
|
* * * |
|
В поле операнда разрешается указывать символические имена двух типов:
символические имена, которые определены (зарезервированы) в самом ассемблере и связаны с внутренней архитектурой микропроцессора;
символические имена, определяемые программистом.
К числу первых относятся идентификаторы внутренних регистров и регистровых пар.
В языке ассемблера микропроцессора используются идентификаторы внутренних регистров В, С, D, Е, Н, L, М, А с соответствующими двоичными значениями от 000 до 111b. Такие идентификаторы являются зарезервированными символами и не могут быть применены в другом качестве.
Пример использования таких идентификаторов: |
|||||
Метка |
Код |
Операнд |
Комментарий |
|
|
;Пример использования символических данных |
|||||
|
MOV |
А, Е |
; Передача из регистра ; Е в аккумулятор ACC |
||
|
* * * |
|
|||
|
MOV |
M,B |
; сохранить В в памяти ; косвенно |
||
|
* * * |
|
В командах, оперирующих 16-битными значениями, применяются идентификаторы внутренних 16-битных регистров ВС, DE, НL, PSW, SP.
Примеры таких команд:
Пример. |
||||
Метка |
Код |
Операнд |
Комментарий |
|
;Пример использования символических данных |
||||
|
LXI |
H, 0BC00h |
; инициализация ; регистровой пары HL |
|
|
* * * |
|
||
|
PUSH |
PSW |
; загрузка в стек ; содержимого ; аккумулятора и ; регистра флагов |
|
|
* * * |
|
Символические имена, определяемые программистом, бывают двух видов
метки;
данные, которым присвоены символические имена.
Метка, вводимая в поле операнда, позволяет избежать указания при программировании абсолютного адреса перехода, заменяя его условной последовательностью символов. Преобразование метки в абсолютный адрес осуществляется компилятором.
Требования к меткам рассматривались ранее в подразделе 1.2.
Символические имена операндам и ячйкам памяти присваиваются с помощью директив EQU, SET, DB, DW, DS (см. Раздел 2); Такой приём повышает читаемость программы, а также обеспечивает ряд преимуществ при внесении в неё изменений.
Примеры определения символических имён: |
|||||||
Метка |
Код |
Операнд |
Комментарий |
|
|||
;Пример определения символических имён |
|||||||
Adr_Op1 |
EQU |
0FF0Bh |
; адрес OP1 в ячейке ; памяти |
||||
MASK |
SET |
01h |
; маска для младшего бита |
||||
|
* * * |
|
Введённые с помощью директив EQU или SET символические имена MASK, Adr_Op1могут быть использованы следующим образом:
Пример. |
|||
Метка |
Код |
Операнд |
Комментарий |
;Пример использования символических имен |
|||
|
LDA |
Add_Op1 |
; Op1 в ACC
|
|
XRI |
MASK |
; младший бит ; инвертировать |
|
* * * |
|
|
|
ANI |
MASK |
; младший бит –выделить |
|
* * * |
|
Символические имена рекомендуется определять в отдельной секции программы, размещая её либо в начале, либо в конце программы. Кроме того, рекомендуется использовать содержательные имена, например, OP, OPER, SUM, REZULT, MULT, COUNT и т.п.