Конспект по AVR ASM
Device: Atmega328P
🔲 Для удобного просмотра таблицы команд разверните файл
Не очень много памяти. 0x0000 - 0xFFFF
Лучше хранит данные, без необходимости их обновлять. 0x0000 - 0xFFFF
-
0x0000 - 0x001F - POH
-
0x0020 - 0x005F - I/O (все данные подключенные к процессору, настройки переферии)
-
0x0060 - RAMEND - Внутренняя SRAM (хранить что хочется)
-
RAMEND+1 - 0xFFFF - Внешняя SRAM
Всегда 32 регистра. В каждом по байту.
Адресация:
- 5 бит
- 4 бит
- 2 бит
2-х битные могут объединяться по парам (X, Y, Z):
- X - 26, 27
- Y - 28, 29
- Z - 30, 31
Данные между включениями и выключениями
SP
(Stack Pointer) - указатель стека, указывает на начало стека. Стек растет в верх, указатель стека вниз. При добавлении элемента указатель стека уменьшается
SPH
, SPL
– Если у МК больше 256 байт памяти для адресации стека требуется 16 бит
.dseg
- Данные после запуска МК
.cseg
- Сегмент кода
.eseg
- EEPROM
RESET
- Код если МК сломан
MAIN
- Код
SREG
- Регистр статуса
Список флагов:
Флаг | Расшифровка | Описание |
---|---|---|
C | Carry | Флаг переноса |
Z | Zero | Флаг нулевого значения |
N | Negative | Флаг отрицательного значения (Старший бит после операции) |
V | Two's complement overflow indictor | Флаг указатель переполнения (Переполнение перешло в знак) |
S | Signed Test | Флаг для проверок со знаком (S = V xor N) |
H | Half Carry | Флаг полупереноса (Переполнение 4 бита) |
T | Transfer bit | Флаг переноски (Используется как временный флаг) |
I | Interrupt Enable Flag | Флаг разрешения глобального прерывания |
Синтаксис команд: <Команда> <Куда> <Откуда>
Список команд:
Команда | Синтаксис | Биты команды | Операнды | Такты | Флаги | Описание |
---|---|---|---|---|---|---|
NOP | NOP | 0000 0000 | 0000 0000 | 1 | Ничего не делать | ||
MOV | MOV Rd, Rr | 0010 11rd | dddd rrrr | 0<=r<=32, 0<=d<=32 | 1 | Копировать регистр | |
LDI | LDI Rd, K | 1110 KKKK | dddd KKKK | 16<=d<=31, 0<=K<=255 | 1 | Загрузить значение в регистр | |
ADD | ADD Rd, Rr | 0000 11rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | H+S+V+N+Z+C+ | Сложить без переноса |
INC | INC Rd | 1001 010d | dddd 0011 | 0<=d<=31 | 1 | S+V+N+Z+ | Инкрементировать |
DEC | DEC Rd | 1001 010d | dddd 1010 | 0<=d<=31 | 1 | S+V+N+Z+ | Декрементировать |
SUB | SUB Rd, Rr | 0001 10rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | H+S+V+N+Z+C+ | Вычесть без переноса |
SUBI | SUBI Rd, K | 0101 KKKK | dddd KKKK | 16<=d<=31, 0<=K<=255 | 1 | H+S+V+N+Z+C+ | Вычесть значение из регистра |
ADIW | ADIW Rdl, K | 1001 0110 | KKdd KKKK | dl {24, 26, 28, 30} (X, Y, Z), 0<=K<=63 | 2 | S+V+N+Z+C+ | Сложить значение с парой регистров (16 бит) |
SBIW | SBIW RDl, K | 1001 0111 | KKdd KKKK | dl {24, 26, 28, 30} (X, Y, Z), 0<=K<=63 | 2 | S+V+N+Z+C+ | Вычесть значение из пары регистров |
ADC | ADC Rd, Rr | 0001 11rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | H+S+V+N+Z+C+ | Сложение двух регистров и содержимого флага переноса |
SBC | SBC Rd, Rr | 0000 10rd | dddd rrrr | 0<=d<= 31, 0<= r<= 31 | 1 | H+S+V+N+Z+C+ | Вычитание содержимого регистра и содержимого флага переноса (С) |
SBCI | SBCI Rd, K | 0100 KKKK | dddd KKKK | 0<=d<= 31, 16<=K<=31 | 1 | H+S+V+N+Z+C+ | Вычитание константы и содержимого флага переноса |
СOM | COM Rd | 1001 010d | dddd 0000 | 0<=d<=31 | 1 | S+V0N+Z+C1 | Перевод в обратный код |
NEG | NEG Rd | 1001 010d | dddd 0001 | 0<=d<=31 | 1 | H+S+V+N+Z+C+ | Перевод в дополнительный код(Значение 0x80 не изменно) |
AND | AND Rd, Rr | 0010 00rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | S+V0N+Z+ | Логические И между двумя регистрами |
ANDI | ANDI Rd, K | 0111 KKKK | dddd KKKK | 16<=d<=31, 0<=K<=255 | 1 | S+V0N+Z+ | Логическое И между регистром и значением |
OR | OR Rd, Rr | 0010 10rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | S+V0N+Z+ | Логическое ИЛИ между двумя регистрами |
ORI | ORI Rd, K | 0110 KKKK | dddd KKKK | 16<=d<=31, 0<=K<=255 | 1 | S+V0N+Z+ | Логическое ИЛИ между ригистром и значением |
EOR | EOR Rd, Rr | 0010 01rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | S+V0N+Z+ | Исключающее ИЛИ между двумя регистрами |
LSL | LSL Rd | 0000 11dd | dddd dddd | 0<=d<=31 | 1 | H+S+V+N+Z+C+ | Логический сдвинуть влево (7-й бит выгружается во флаг переноса (C)) |
LSR | LSR Rd | 1001 010d | dddd 0110 | 0<=d<=31 | 1 | S+V+N0Z+C+ | Логически сдвинуть вправо |
ROL | ROL Rd | 0001 11dd | dddd dddd | 0<=d<=31 | 1 | H+S+V+N+Z+C+ | Логически сдвинуть влево через перенос (Флаг переноса (С) смещается на место бита 0 регистра Rd. Бит 7 смещается во флаг переноса (С)) |
ROR | ROR Rd | 1001 010d | dddd 0111 | 0<=d<=31 | 1 | S+V+N+Z+C+ | Логически сдвинуть вправо через перенос (Флаг переноса (С) на место 0-го бита, 7-й бит смещается во флаг переноса (С)) |
ASR | ASR Rd | 1001 010d | dddd 0101 | 0<=d<=31 | 1 | S+V+N+Z+C+ | Арифметически сдвинуть вправо (Флаг переноса (С) смещается на место 7-го бита, 0-й бит выгружается во флаг переноса (С)) |
SEP | SEP Rd | 1110 1111 | dddd 1111 | 16<=d<=31 | 1 | Включить все биты регистра | |
CLR | CLR Rd | 0010 01dd | dddd dddd | 0<=d<=31 | 1 | S0V0N0Z1 | Очистить регистр |
RJMP | RJMP k | 1100 kkkk | kkkk kkkk | -2K≤k≤2K | 2 | Перейти относительно | |
JMP | JMP k | 1001 010k | kkkk 110k | kkkk kkkk | kkkk kkkk | 0<=k<=4M | 3 | Перейти абсолютно | |
BRCC | BRCC k | 1111 01kk | kkkk k000 | -64<=k<=63 | 1 or 2 | Перейти если флаг С очищен | |
BRCS | BRCS k | 1111 00kk | kkkk k000 | -64<=k<=63 | 1 or 2 | Перейти если флаг С установлен | |
BRNE | BRNE k | 1111 01kk | kkkk k001 | -64<=k<=63 | 1 or 2 | Перейти если флаг Z очищен | |
BREQ | BREQ k | 1111 00kk | kkkk k001 | -64<=k<=63 | 1 or 2 | Перейти если флаг Z установлен | |
CP | CP Rd, Rr | 0001 01rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | H+S+V+N+Z+C+ | Сравнить без переноса |
CPC | CPC Rd, Rr | 0000 01rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1 | H+S+V+N+Z+C+ | Сравнить с учетом переноса |
CPI | CPI Rd, K | 0011 KKKK | dddd KKKK | 16<=d<=31 | 1 | H+S+V+N+Z+C+ | Сравнить с константой |
CPSE | CPSE Rd, Rr | 0001 00rd | dddd rrrr | 0<=d<=31, 0<=r<=31 | 1or2or3 | H+S+V+N+Z+C+ | Сравнить и пропустить если равно |
OUT | OUT P, Rr | 1011 1PPr | rrrr PPPP | 0<=r<=31, 0<=P,=63 | 1 | Записать данные из регистра в порт I/O | |
PUSH | PUSH Rd | 1001 001d | dddd 1111 | 0<=d<=31 | 2 | Загрузить регистр в стек | |
POP | POP Rd | 1001 000d | dddd 1111 | 0<=d<=31 | 2 | Загрузить значение из стека в регистр | |
IN | IN Rd, P | 1011 0PPd | dddd PPPP | 0<=d<=31, 0<=P<=63 | 1 | Загрузить данные из порта I/O в регистр | |
RCALL | RCALL k | 1101 kkkk | kkkk kkkk | 0<=k<=4095 | 3 | Вызов процедуры находящейся по адресу удаленному от текущему PC на k. Адрес возврата в стеке | |
CALL | CALL k | 1001 010k | kkkk 111k | kkkk kkkk kkkk kkkk | 0<=k<=4194303 | 4 | Вызов процедуры находящейся по адресу k. Адрес возврата в стеке | |
RET | RET | 1001 0101 | 0XX0 1000 | 4 | Возвращает из подпрограммы. Адрес возврата берется из стека | ||
STS | STS k, Rr | 1001 001d | dddd 0000 | kkkk kkkk kkkk kkkk | 0<=d<=31, 0<=k<=65535 | 3 | Загрузить значение в SRAM | |
LDS | LDS Rd, k | 1001 000d | dddd 0000 | kkkk kkkk kkkk kkkk | 0<=d<=31, 0<=k<=65535 | 3 | Выгрузить значение из SRAM | |
ST | ST X(X+)(-X), Rr | 1001 001r | rrrr 1100(01)(10) | 0<=r<=31 | 2 | Записать из регистра в SRAM | |
SEI | SEI | 1001 0100 | 0111 1000 | 1 | I1 | Установить флаг глобального прерывания | |
CLI | CLI | 1001 0100 | 1111 1000 | 1 | I0 | Очистить флаг глобального прерывания |
- Сложение 5 и -5:
LDI R16, 5
LDI R18, 5
NEG R18
ADD R16, R18 ; 5 + (-5)
- Swap двух регистров без временного регистра:
A = A xor B
B = A xor B
A = A xor B
- Загрузить старшие биты числа 1234 в регистр R28, а в регистр R29 записать младшие биты числа 1234:
LDI R28, low(1234)
LDI R29, high(1234)
- Цикл со счетчиком используя условный переход BRNE:
LDI R16, 4
LOOP:
NOP
DEC R16
BRNE LOOP
-
Инициализация стека:
LDI R16, Low(RAMEND)
OUT SPL, R16
LDI R16, High(RAMEND)
OUT SPH, R16