Ассемблер
· Введение
Ассемблер преобразовывает (транслирует) исходные файлы ассемблера в объектные файлы в машинном коде. Эти файлы находятся в общем формате объектного файла (COFF). Исходные файлы могут содержать следующие инструкции ассемблера:
· Директивы Ассемблера.
· Макро директивы.
· Команды ассемблера.
· Формат инструкций исходника
Компилятор работает с исходными файлами, содержащими инструкции, метки и директивы. Инструкции и директивы, как правило, имеют один или несколько операндов.
Строка кода не должна быть длиннее 120 символов.
Строка ассемблерного кода завершается символом Enter. Строка содержит поля, разделенные пробелами. Строка может иметь одну из 4 форм:
· [метка:] директива [операнды] [Комментарий]
· [метка:] инструкция [операнды] [Комментарий]
· Комментарий
· Пустая строка
Позиции, указанные в квадратных скобках, необязательны.
Ассемблер не различает регистр символов.
Любая строка может начинаться с метки, которая является набором символов, заканчивающимся двоеточием. Метки используются для указания места, в которое передаётся управление при переходах, а также для задания имён переменных.
|
|
Операнды разделяются запятыми (без пробелов).
Текст после точки с запятой (;) и до конца строки – это комментерий. Он игнорируется компилятором. Комментарий имеет следующую форму:
; [Текст]
Компилятор не требует, чтобы метки, директивы, комментарии или инструкции находились в определённой колонке строки.
Примеры:
label:.EQU var1=100; Устанавливает var1=100 (это помеченная директива).
.EQU var2=200; Устанавливает var2=200 (это директива).
; Строка с одним только комментарием
Операнды в командах могут быть таких видов:
· Rd: Результирующий (и исходный) регистр в регистровом файле
· Rr: Исходный регистр в регистровом файле
· b: Константа (3 бита), может быть константное выражение
· s: Константа (3 бита), может быть константное выражение
· P: Константа (5-6 бит), может быть константное выражение
· K6; Константа (6 бит), может быть константное выражение
· K8: Константа (8 бит), может быть константное выражение
· k: Константа (размер зависит от инструкции), может быть константное выражение
· q: Константа (6 бит), может быть константное выражение
· Rdl:═ R24, R26, R28, R30. Для инструкций ADIW и SBIW
· X,Y,Z: Регистры косвенной адресации (X=R27:R26, Y=R29:R28, Z=R31:R30)
Используемые обозначения
Символика | Назначение | Комментарий |
SREG | Регистр состояния | Адрес $3F |
C | Флаг переноса | Разряд 0 в регистре SREG |
Z | Флаг нулевого результата | Разряд 1 в регистре SREG |
N | Флаг отрицательного результата | Разряд 2 в регистре SREG |
V | Флаг переполнения | Разряд 3 в регистре SREG |
S | Флаг знака | Разряд 4 в регистре SREG |
II | Флаг половинного переноса | Разряд 5 в регистре SREG |
T | Флаг копирования | Разряд 6 в регистре SREG |
I | Флаг разрешения прерываний | Разряд 7 в регистре SREG |
Rd | Регистр назначения | |
Rr | Регистр передающий | |
R | Регистр результата | |
Kn | n-битная константа | |
X, Y, Z | Указатели при косвенной адресации | X = R27:R26 Y = R29:R28 Z = R31:R30 |
Rdl | Младший байт регистровой пары | Пара Rdh:Rdl |
Rdh | Старший байт регистровой пары | Пара Rdh:Rdl |
P | Адрес порта ввода/вывода | |
q | Смещение при косвенной адресации | |
Стек | Область памяти для хранения адреса возврата или промежуточного значения | |
SP | Указатель стека | |
X | Обозначает разряды, устанавливаемые ассемблером в 0. |
· Команды условного перехода c учетом знака
|
|
Условие | Команда | Пояснение |
Rd ≥ Rr? | brge | Переход, если Rd ≥Rr (S=0) |
Rd = Rr? | breq | Переход, если Rd = Rr (Z=1) |
Rd < Rr? | brlt | Переход, если Rd < Rr (S=1) |
· Команды прямого опроса флагов
Условие | Команда | Пояснение |
C? | brcs | Переход по переносу (C = 1) |
C? | brcc | Переход, если переноса нет (C = 0) |
Z? | breq | Переход по нулю (Z = 1) |
Z? | brne | Переход по не нулю (Z = 0) |
N? | brmi | Переход по минусу (N = 1) |
N? | brpl | Переход по плюсу(N = 0) |
V? | brvs | Переход по переполнению (V = 1) |
V? | brvc | Переход, если переполнения нет (V = 0) |
· Арифметические и логические команды
Мнемоника | Описание | Действие | Циклы | Примеч. |
ADD Rd,Rr | Сложить | Rd < Rd+Rr | ||
ADDI Rd,K | Сложить с константой | Rd < Rd+K | ||
ADС Rd,Rr | Сложить с переносом | Rd < Rd+Rr+С | ||
ADСI Rd,Rr | Сложить константу с переносом | Rd < Rd+K+С | ||
ADW Rdl,Rr | Сложить слово с константой | Rdh,l < Rdh,l+K | Rdl - парный | |
SUB Rd,Rr | Вычесть | Rd < Rd-Rr | ||
SUBI Rd,K | Вычесть константу | Rd <- Rd-K | ||
SBС Rd,Rr | Вычесть с переносом | Rd < Rd-Rr-С | ||
SBСI Rd,Rr | Вычесть константу с переносом | Rd < Rd-K-С | ||
SBW Rdl,Rr | Вычесть слово с константой | Rdh,l <- Rdh,l-K | Rdl - парный | |
AND Rd,Rr | Логическое И | Rd < Rd AND Rr | ||
ANDI Rd,K | Логическое И с константой | Rd < Rd AND K | ||
OR Rd,Rr | Логическое ИЛИ | Rd < Rd OR Rr | ||
ORI Rd,K | Логическое ИЛИ с константой | Rd < Rd OR K | ||
EOR Rd,Rr | Исключающее ИЛИ | Rd < Rd XOR Rr | ||
COM Rd | Дополнение до 1 | Rd < $FF-Rd | ||
NEG Rd | Дополнение до 2 | Rd < $00-Rd | ||
SBR Rd,K | Установить биты | Rd < Rd OR K | ||
CBR Rd,K | Сбросить биты | Rd < Rd AND K | ||
INC Rd | Увеличить на 1 | Rd < Rd+1 | ||
DEC Rd | Уменьшить на 1 | Rd < Rd-1 | ||
TST Rd | Проверить на 0 или 1 | Rd < Rd AND Rd | ||
CLR Rd | Очистить | Rd < Rd XOR Rd | Все 0 | |
ER Rd | Установить | Rd < $FF | Все 1 |
· Команды ветвления
Мнемоника | Описание | Действие | Флаги | Циклы |
RJMP k | Относительный переход | PC < PC+k+1 | Нет | |
LJMP k | Переход по адресу (Z) | PC < Z | Нет | |
RCALL k | Относительный вызов подпрограммы | PC < PC+k+1 | Нет | |
ICALL | Вызов подпрограммы по адресу (Z) | PC < Z | Нет | |
RET | Выход из подпрограммы | PC < STACK | Нет | |
RETI | Выход из прерывания | PC < STACK | I | |
CPSE Rd,Rr | Сравнить, пропуск при равно | If(Rd=Rr) PC<PC+2 или 3 | Z,N,V,C,H | 1/2 |
CP Rd,Rr | Сравнить | Rd-Rr | Z,N,V,C,H | |
CPC Rd,Rr | Сравнить с прерыванием | Rd-Rr-C | Z,N,V,C,H | |
CPI Rd,K | Сравнить с константой | Rd-C | Z,N,V,C,H | |
SBRC Rr,b | Пропуск, если в Rr бит b сброшен | If(Rr(b)=0) PC<PC+2 или 3 | Нет | 1/2 |
SBRS Rr,b | Пропуск, если в Rr бит b установлен | If(Rr(b)=1) PC<PC+2 или 3 | Нет | 1/2 |
SBIC P,b | Пропуск, если в регистре ввода/вывода P бит b сброшен | If(P(b)=0) PC<PC+2 или 3 | Нет | 1/2 |
SBIS P,b | Пропуск, если в регистре ввода/вывода P бит b установлен | If(P(b)=1) PC<PC+2 или 3 | Нет | 1/2 |
BRBS s,k | Переход, если в SREG установлен флаг s | If(SREG(s)=1) PC<PC+1+k | Нет | 1/2 |
BRBS s,k | Переход, если в SREG сброшен флаг s | If(SREG(s)=0) PC<PC+1+k | Нет | 1/2 |
BREQ k | Переход, если равно | If(Z=1) PC<PC+1+k | Нет | 1/2 |
BRNE k | Переход, если не равно | If(Z=0) PC<PC+1+k | Нет | 1/2 |
BRCS k | Переход, если перенос установлен | If(C=1) PC<PC+1+k | Нет | 1/2 |
BRCC k | Переход, если перенос сброшен | If(C=0) PC<PC+1+k | Нет | 1/2 |
BRSH k | Переход, если равно или больше | If(C=0) PC<PC+1+k | Нет | 1/2 |
BRLO k | Переход, если меньше | If(C=1) PC<PC+1+k | Нет | 1/2 |
BRMI k | Переход, если минус | If(N=1) PC<PC+1+k | Нет | 1/2 |
BRPL k | Переход, если плюс | If(N=0) PC<PC+1+k | Нет | 1/2 |
BRGE k | Переход, если больше или равно | If(N XOR V=0) PC<PC+1+k | Нет | 1/2 |
BRLT k | Переход, если меньше 0 | If(N XOR V=1) PC<PC+1+k | Нет | 1/2 |
BRHS k | Переход, если флаг H установлен | If(H=1) PC<PC+1+k | Нет | 1/2 |
BRHC k | Переход, если флаг H сброшен | If(H=0) PC<PC+1+k | Нет | 1/2 |
BRTS k | Переход, если флаг T установлен | If(H=1) PC<PC+1+k | Нет | 1/2 |
BRTC k | Переход, если флаг T сброшен | If(H=0) PC<PC+1+k | Нет | 1/2 |
BRVS k | Переход, если флаг V установлен | If(H=1) PC<PC+1+k | Нет | 1/2 |
BRVC k | Переход, если флаг V сброшен | If(H=0) PC<PC+1+k | Нет | 1/2 |
BRIE k | Переход, если прерывания азрешены | If(I=1) PC<PC+1+k | Нет | 1/2 |
BRID k | Переход, если прерывания запрещены | If(I=0) PC<PC+1+k | Нет | 1/2 |
· Команды пересылок
|
|
Мнемоника | Описание | Действие | Флаги | Циклы |
MOV Rd,Rr | Пересылка между регистрами | Rd < Rr | Нет | |
LDI Rd,K | Загрузить константу | Rd < K | Нет | |
LD Rd,X | Загрузить регистр непосредственно | Rd < (X) | Нет | |
LD Rd,X+ | Загрузить регистр непосредственно с постинкрементом | Rd < (X) X < X+1 | Нет | |
LD Rd,-X | Загрузить регистр непосредственно с предварительным декрементом | X < X-1 Rd < (X) | Нет | |
LD Rd,Y | Загрузить регистр непосредственно | Rd < (Y) | Нет | |
LD Rd,Y+ | Загрузить регистр непосредственно с постинкрементом | Rd < (Y) Y < Y+1 | Нет | |
LD Rd,-Y | Загрузить регистр непосредственно с предварительным декрементом | Y < Y-1 Rd < (Y) | Нет | |
LDD Rd,Y+q | Загрузить регистр непосредственно по адресу в Y со смещением q | Rd < (Y+k) | Нет | |
LD Rd,Z | Загрузить регистр непосредственно | Rd < (Z) | Нет | |
LD Rd,Z+ | Загрузить регистр непосредственно с постинкрементом | Rd < (Z) Z < Z+1 | Нет | |
LD Rd,-Z | Загрузить регистр непосредственно с предварительным декрементом | Z < Z-1 Rd < (Z) | Нет | |
LDD Rd,Z+q | Загрузить регистр непосредственно со смещением | Rd < (Z+k) | Нет | |
LDS Rd,k | Загрузить регистр из ОЗУ по адресу (k) | Rd < (k) | Нет | |
ST X,Rr | Сохранить регистр непосредственно по адресу в X | (X) < Rr | Нет | |
ST X+,Rr | Сохранить регистр непосредственно по адресу в X с постинкрементом | (X) < Rr X < X+1 | Нет | |
ST -X,Rr | Сохранить регистр непосредственно по адресу в X с предварительным декрементом | X < X-1 (X) < Rr | Нет | |
STD X+q,Rr | Сохранить регистр непосредственно по адресу в X со смещением q | (X+q) < Rr | Нет | |
ST Y,Rr | Сохранить регистр непосредственно по адресу в Y | (Y) < Rr | Нет | |
ST Y+,Rr | Сохранить регистр непосредственно по адресу в Y с постинкрементом | (Y) < Rr Y < Y+1 | Нет | |
ST -Y,Rr | Сохранить регистр непосредственно по адресу в Y с предварительным декрементом | Y < Y-1 (Y) < Rr | Нет | |
STD Y+q,Rr | Сохранить регистр непосредственно по адресу в Y со смещением q | (Y+q) < Rr | Нет | |
ST Z,Rr | Сохранить регистр непосредственно по адресу в Z | (Z) < Rr | Нет | |
ST Z+,Rr | Сохранить регистр непосредственно по адресу в Z с постинкрементом | (Z) < Rr Z < Z+1 | Нет | |
ST -Z,Rr | Сохранить регистр непосредственно по адресу в Z с предварительным декрементом | Z < Z-1 (Y) < Rr | Нет | |
STS k,Rr | Сохранить регистр в ОЗУ по адресу (k) | (k) < Rr | Нет | |
LPM | Загрузка из памяти программ по адресу в Z | R0 < (Z) | Нет | |
IN Rd,P | Ввод в регистр из порта P | Rd < P | Нет | |
OUT P,Rr | Вывод из регистра в порт P | P < Rr | Нет | |
PUSH Rr | Сохранить регистр в стеке | STACK < Rr | Нет | |
POP Rd | Загрузить регистр из стека | Rd < STACK | Нет |
· Команды работы с битами
|
|
Мнемоника | Описание | Действие | Флаги | Циклы |
SBI P,b | Установить бит b в регистре ввода/вывода P | I/O (P,b) < 1 | Нет | |
CBI P,b | Сбросить бит b в регистре ввода/вывода P | I/O (P,b) < 0 | Нет | |
LSL Rd | Логический сдвиг влево на 1 бит в регистре | Rd(n+1) < Rd(n) Rd(0) < 0 | Z,C,N,V | |
LSR Rd | Логический сдвиг вправо на 1 бит в регистре | Rd(n) < Rd(n+1) Rd(7) < 0 | Z,C,N,V | |
ROL Rd | Сдвиг влево через С на 1 бит в регистре | Rd(0) < C Rd(n+1) < Rd(n) C < Rd(7) | Z,C,N,V | |
ROR Rd | Сдвиг вправо через С на 1 бит в регистре | Rd(7) < C Rd(n) < Rd(n+1) C < Rd(0) | Z,C,N,V | |
LSR Rd | Логический сдвиг вправо на 1 бит в регистре | Rd(n) < Rd(n+1) Rd(7) < 0 | Z,C,N,V | |
SWAP Rd | Обмен ниблов (полубайт) в регистре | Rd(3…0) < Rd(7…4) Rd(7…4) < Rd(3…0) | Нет | |
BSET s | Установить флаг s | SREG(s) < 1 | SREG(s) | |
BCLEAR s | Сбросить флаг s | SREG(s) < 0 | SREG(s) | |
BST Rr,b | Запомнить бит b регистра в флаге T | T < Rr(b) | T | |
BLD Rd,b | Прочитать бит из T в бит b регистра | Rd(b)< T | Нет | |
SEC | Установить перенос | C < 1 | C | |
CLC | Сбросить перенос | C < 0 | C | |
SEN | Установить флаг N | N < 1 | N | |
CLN | Сбросить флаг N | N < 0 | N | |
SEZ | Установить флаг Z | Z < 1 | Z | |
CLZ | Сбросить флаг Z | Z < 0 | Z | |
SES | Установить флаг S | S < 1 | S | |
CLS | Сбросить флаг S | S < 0 | S | |
SEV | Установить флаг V | V < 1 | V | |
CLV | Сбросить флаг V | V < 0 | V | |
SET | Установить флаг T | T < 1 | T | |
CLT | Сбросить флаг T | T < 0 | T | |
SEH | Установить флаг H | H < 1 | H | |
CLH | Сбросить флаг H | H < 0 | H | |
NOP | Нет операции | Нет | ||
SLEEP | Останов | Нет | ||
WDR | Сброс сторожевого таймера | Нет |