§ Флаги
7 6 5 4 3 2 1 0
I T H S V N Z C
I - Interrupt
T - Temporary
H - Half Carry
S - Sign
V - Overflow
N - Negative
Z - Zero
C - Carry
§ Инструкции процессора
FEDC BA98 7654 3210 |
Опкод |
Оп.1 |
Оп.2 |
Tакты |
Описание |
MASK |
= |
УМНОЖЕНИЯ |
---|
1001 11rd dddd rrrr | MUL | Rd | Rr | 1 | Умножение | FC00 | 9C00 |
---|
0000 0010 dddd rrrr | MULS | Rd | Rr | 1 | Знаковое умножение | FF00 | 0200 |
---|
0000 0011 0ddd 0rrr | MULSU | Rd | Rr | 1 | Беззнаковое умножение | FF88 | 0300 |
---|
0000 0011 0ddd 1rrr | FMUL | Rd | Rr | 1 | Дробное умножение | FF88 | 0308 |
---|
0000 0011 1ddd 0rrr | FMULS | Rd | Rr | 1 | Дробное знаковое умножение | FF88 | 0380 |
---|
0000 0011 1ddd 1rrr | FMULSU | Rd | Rr | 1 | Дробное беззнаковое умножение | FF88 | 0388 |
---|
АРИФМЕТИЧЕСКИЙ (2 РЕГИСТРА) |
---|
0000 01rd dddd rrrr | CPC | Rd | Rr | 1 | Сравнить с переносом | FC00 | 0400 |
---|
0000 10rd dddd rrrr | SBC | Rd | Rr | 1 | Вычитание с переносом | FC00 | 0800 |
---|
0000 11rd dddd rrrr | ADD | Rd | Rr | 1 | Сложение | FC00 | 0C00 |
---|
0001 01rd dddd rrrr | CP | Rd | Rr | 1 | Сравнение | FC00 | 1400 |
---|
0001 10rd dddd rrrr | SUB | Rd | Rr | 1 | Вычитание | FC00 | 1800 |
---|
0001 11rd dddd rrrr | ADC | Rd | Rr | 1 | Сложение с переносом | FC00 | 1C00 |
---|
0010 00rd dddd rrrr | AND | Rd | Rr | 1 | Логическое И | FC00 | 2000 |
---|
0010 01rd dddd rrrr | EOR | Rd | Rr | 1 | Логическое исключающее ИЛИ | FC00 | 2400 |
---|
0010 10rd dddd rrrr | OR | Rd | Rr | 1 | Логическое ИЛИ | FC00 | 2800 |
---|
АРИФМЕТИЧЕСКИЙ (ОПЕРАНД + IMMEDIATE) |
---|
0011 KKKK dddd KKKK | CPI | Rd | K | 1 | Сравнение с Imm8 | F000 | 3000 |
---|
0100 KKKK dddd KKKK | SBCI | Rd | K | 1 | Вычитание Imm8 с переносом | F000 | 4000 |
---|
0101 KKKK dddd KKKK | SUBI | Rd | K | 1 | Вычитание Imm8 | F000 | 5000 |
---|
0110 KKKK dddd KKKK | ORI | Rd | K | 1 | Логическое ИЛИ с Imm8 | F000 | 6000 |
---|
0111 KKKK dddd KKKK | ANDI | Rd | K | 1 | Логическое И с Imm8 | F000 | 7000 |
---|
1001 0110 KKdd KKKK | ADIW | Rd+1:Rd | K | 1 | Сложение r25:24, r27:26, r29:28, r31:30 + K | FF00 | 9600 |
---|
1001 0111 KKdd KKKK | SBIW | Rd+1:Rd | K | 1 | Вычитание r25:24, r27:26, r29:28, r31:30 - K | FF00 | 9700 |
---|
УСЛОВНЫЕ И БЕЗУСЛОВНЫЕ ПЕРЕХОДЫ |
---|
1100 kkkk kkkk kkkk | RJMP | k | | 1 | Относительный переход | F000 | C000 |
---|
1101 kkkk kkkk kkkk | RCALL | k | | 1 | Относительный вызов процедуры | F000 | D000 |
---|
1001 0101 0000 1000 | RET | | | 1 | Выход из процедуры | FFFF | 9508 |
---|
1001 0101 0001 1000 | RETI | | | 1 | Выход из прерывания | FFFF | 9518 |
---|
1111 00kk kkkk ksss | BRBS | s | k | 1 | Переход если бит установлен во флагах | FC00 | F000 |
---|
1111 01kk kkkk ksss | BRBC | s | k | 1 | Переход если бит сброшен | FC00 | F400 |
---|
1111 110d dddd 0bbb | SBRC | Rd | b | 1 | Пропуск следующей инструкции, если бит очищен в регистре | FE08 | FC00 |
---|
1111 111d dddd 0bbb | SBRS | Rd | b | 1 | Пропуск следующей инструкции, если бит установлен в регистре | FE08 | FE00 |
---|
1001 1001 AAAA Abbb | SBIC | A | b | 1 | Пропуск следующей инструкции, если бит очищен в порту A | FF00 | 9900 |
---|
1001 1011 AAAA Abbb | SBIS | A | b | 1 | Пропуск следующей инструкции, если бит установлен в порту A | FF00 | 9B00 |
---|
0001 00rd dddd rrrr | CPSE | Rd | Rr | 1 | Сравнить (и пропуск следующего) | FC00 | 1000 |
---|
1001 0101 0000 1001 | ICALL | | | 1 | Непрямой вызов процедуры | FFFF | 9509 |
---|
1001 0101 0001 1001 | EICALL | | | 1 | Непрямой вызов процедуры (длинный) | FFFF | 9519 |
---|
1001 0100 0000 1001 | IJMP | | | 1 | Непрямой переход | FFFF | 9409 |
---|
1001 0100 0001 1001 | EIJMP | | | 1 | Непрямой переход (длинный) | FFFF | 9419 |
---|
1001 010k kkkk 111k kkkk kkkk kkkk kkkk | CALL | k2 | | 2 | Длинный вызов процедуры (2 или 3 байта) | FE0E | 940E |
---|
1001 010k kkkk 110k kkkk kkkk kkkk kkkk | JMP | k2 | | 2 | Длинный переход (2 или 3 байта) | FE0E | 940C |
---|
ПЕРЕМЕЩЕНИЯ |
---|
1110 KKKK dddd KKKK | LDI | Rd | K | 1 | Загрузка Immediate в регистр | F000 | E000 |
---|
0010 11rd dddd rrrr | MOV | Rd | Rr | 1 | Перемешщение 8 бит | FC00 | 2C00 |
---|
1001 000d dddd 0000 kkkk kkkk kkkk kkkk | LDS | Rd | k2 | 2 | Загрузить в Rd из памяти (16 бит) | FE0F | 9000 |
---|
1010 1kkk dddd kkkk | STS | Rd | k | 1 | Загрузка в память 0x40 | k | F800 | A800 |
---|
1010 0kkk dddd kkkk | LDS | Rd | k | 1 | Загрузка из памяти 0x40 | k | F800 | A000 |
---|
1001 001d dddd 0000 kkkk kkkk kkkk kkkk | STS | k2 | Rd | 2 | Сохранить Rd в память (16 бит) | FE0F | 9200 |
---|
0000 0001 dddd rrrr | MOVW | Rd+1:Rd | Rr+1:Rr | 1 | Перемещение 16 бит | FF00 | 0100 |
---|
1111 100d dddd 0bbb | BLD | Rd | b | 1 | Rd[b] = T Загружает из SREG[T] | FE08 | F800 |
---|
1111 101d dddd 0bbb | BST | Rd | b | 1 | T = Rd[b] Сохраняет в SREG[T] | FE08 | FA00 |
---|
1001 001d dddd 0100 | XCH | Rd | | 1 | Обмен Rd и (Z) | FE0F | 9204 |
---|
ОДНООПЕРАНДНЫЕ ИНСТРУКЦИИ |
---|
1001 010d dddd 0011 | INC | Rd | | 1 | Rd = Rd + 1 | FE0F | 9403 |
---|
1001 010d dddd 1010 | DEC | Rd | | 1 | Rd = Rd - 1 | FE0F | 940A |
---|
1001 010d dddd 0110 | LSR | Rd | | 1 | Логический сдвиг вправо | FE0F | 9406 |
---|
1001 010d dddd 0101 | ASR | Rd | | 1 | Арифметический сдвиг вправо | FE0F | 9405 |
---|
1001 010d dddd 0111 | ROR | Rd | | 1 | Сдвиг вправо с заемом из Carry | FE0F | 9407 |
---|
1001 010d dddd 0001 | NEG | Rd | | 1 | Rd = $00 - Rd | FE0F | 9401 |
---|
1001 010d dddd 0000 | COM | Rd | | 1 | Rd = Rd ^ 0xFF | FE0F | 9400 |
---|
1001 010d dddd 0010 | SWAP | Rd | | 1 | Обменять нибблы | FE0F | 9402 |
---|
1001 001d dddd 0110 | LAC | Rd | | 1 | Rd = ($FF - Rd) & (Z) | FE0F | 9206 |
---|
1001 001d dddd 0101 | LAS | Rd | | 1 | Rd = Rd | (Z) | FE0F | 9205 |
---|
1001 001d dddd 0111 | LAT | Rd | | 1 | Rd = Rd ^ (Z) | FE0F | 9207 |
---|
1001 0100 1sss 1000 | BCLR | s | | 1 | Очистка флага в SREG | FF8F | 9488 |
---|
1001 0100 0sss 1000 | BSET | s | | 1 | Установка флага в SREG | FF8F | 9408 |
---|
1001 1000 AAAA Abbb | CBI | A | b | 1 | Очистка бита b в порту A | FF00 | 9800 |
---|
1001 1010 AAAA Abbb | SBI | A | b | 1 | Установка бита b в порту A | FF00 | 9A00 |
---|
КОСВЕННАЯ ЗАГРУЗКА |
---|
1001 000d dddd 1100 | LD | Rd | X | 1 | Rd = (X) | FE0F | 900C |
---|
1001 000d dddd 1101 | LD | Rd | X+ | 2 | Rd = (X), X++ | FE0F | 900D |
---|
1001 000d dddd 1110 | LD | Rd | -X | 3 | X--, Rd = (X) | FE0F | 900E |
---|
1001 000d dddd 1001 | LD | Rd | Y+ | 2 | Rd = (Y), Y++ | FE0F | 9009 |
---|
1001 000d dddd 1010 | LD | Rd | -Y | 3 | Y--, Rd = (Y) | FE0F | 900A |
---|
10q0 qq0d dddd 1qqq | LDD | Rd | Y+q | 2 | Rd = (Y+q) | D208 | 8008 |
---|
1001 000d dddd 0001 | LD | Rd | Z+ | 2 | Rd = (Z), Z++ | FE0F | 9001 |
---|
1001 000d dddd 0010 | LD | Rd | -Z | 3 | Z--, Rd = (Z) | FE0F | 9002 |
---|
10q0 qq0d dddd 0qqq | LDD | Rd | Z+q | 2 | Rd = (Z+q) | D208 | 8000 |
---|
КОСВЕННОЕ СОХРАНЕНИЕ |
---|
1001 001r rrrr 1100 | ST | X | Rr | 1 | (X) = Rd | FE0F | 920C |
---|
1001 001r rrrr 1101 | ST | X+ | Rr | 2 | (X) = Rd, X++ | FE0F | 920D |
---|
1001 001r rrrr 1110 | ST | -X | Rr | 3 | X--, (X) = Rd | FE0F | 920E |
---|
1001 001r rrrr 1001 | ST | Y+ | Rr | 2 | (Y) = Rd, Y++ | FE0F | 9209 |
---|
1001 001r rrrr 1010 | ST | -Y | Rr | 3 | Y--, (Y) = Rd | FE0F | 920A |
---|
10q0 qq1r rrrr 1qqq | STD | Y+q | Rr | 2 | (Y+q) = Rd | D208 | 8208 |
---|
1001 001r rrrr 0001 | ST | Z+ | Rr | 2 | (Z) = Rd, Z++ | FE0F | 9201 |
---|
1001 001r rrrr 0010 | ST | -Z | Rr | 3 | Z--, (Z) = Rd | FE0F | 9202 |
---|
10q0 qq1r rrrr 0qqq | STD | Z+q | Rr | 2 | (Z+q) = Rd | D208 | 8200 |
---|
ЗАГРУЗКА И ЗАПИСЬ В ПАМЯТЬ ПРОГРАММ |
---|
1001 0101 1100 1000 | LPM | R0 | Z | 1 | R0 = (Z) | FFFF | 95C8 |
---|
1001 000d dddd 0100 | LPM | Rd | Z | 1 | Rd = (Z) | FE0F | 9004 |
---|
1001 000d dddd 0101 | LPM | Rd | Z+ | 1 | Rd = (Z), Z++ | FE0F | 9005 |
---|
1001 0101 1101 1000 | ELPM | R0 | Z | 1 | R0 = (Z) | FFFF | 95D8 |
---|
1001 000d dddd 0110 | ELPM | Rd | Z | 1 | Rd = (Z) | FE0F | 9006 |
---|
1001 000d dddd 0111 | ELPM | Rd | Z+ | 1 | Rd = (Z), Z++ | FE0F | 9007 |
---|
1001 0101 1110 1000 | SPM | | | 1 | Запись в память программ | FFFF | 95E8 |
---|
1001 0101 1111 1000 | SPM.2 | | | 1 | Запись в память программ | FFFF | 95F8 |
---|
УПРАВЛЕНИЕ ПРОЦЕССОРОМ |
---|
1001 0101 1000 1000 | SLEEP | | | 1 | Остановка процессора | FFFF | 9588 |
---|
1001 0101 1010 1000 | WDR | | | 1 | Сброс сторожевого пса (дать ему косточку) | FFFF | 95A8 |
---|
1001 0101 1001 1000 | BREAK | | | 1 | Остановка процессора | FFFF | 9598 |
---|
0000 0000 0000 0000 | NOP | | | 1 | Нет операции | FFFF | 0000 |
---|
РАЗНОЕ |
---|
1011 0AAd dddd AAAA | IN | Rd | A | 1 | Извлечение данных из порта А в регистр Rr | F800 | B000 |
---|
1011 1AAr rrrr AAAA | OUT | A | Rr | 1 | Вывод в порт A регистра Rr | F800 | B800 |
---|
1001 001d dddd 1111 | PUSH | Rd | | 1 | Сохранить значение в стек | FE0F | 920F |
---|
1001 000d dddd 1111 | POP | Rd | | 1 | Восстановить из стека | FE0F | 900F |
---|
1001 0100 KKKK 1011 | DES | K | | 1 | Выполнение операции шифрования | FF0F | 940B |
---|
§ Декодер инструкции
switch (opcode & 0xD208) {
case 0x8000: mnem = 'ldd'; break; // Rd, Z+q
case 0x8008: mnem = 'ldd'; break; // Rd, Y+q
case 0x8200: mnem = 'std'; break; // Z+q, Rr
case 0x8208: mnem = 'std'; break; // Y+q, Rr
}
switch (opcode & 0xF000) {
case 0xC000: mnem = 'rjmp'; break; // k
case 0xD000: mnem = 'rcall'; break; // k
case 0xE000: mnem = 'ldi'; break; // Rd, K
case 0x3000: mnem = 'cpi'; break; // Rd, K
case 0x4000: mnem = 'sbci'; break; // Rd, K
case 0x5000: mnem = 'subi'; break; // Rd, K
case 0x6000: mnem = 'ori'; break; // Rd, K
case 0x7000: mnem = 'andi'; break; // Rd, K
}
switch (opcode & 0xF800) {
case 0xA000: mnem = 'lds'; break; // Rd, k
case 0xA800: mnem = 'sts'; break; // Rd, k
case 0xB000: mnem = 'in'; break; // Rd, A
case 0xB800: mnem = 'out'; break; // A, Rr
}
switch (opcode & 0xFC00) {
case 0x0400: mnem = 'cpc'; break; // Rd, Rr
case 0x0800: mnem = 'sbc'; break; // Rd, Rr
case 0x0C00: mnem = 'add'; break; // Rd, Rr
case 0x1C00: mnem = 'adc'; break; // Rd, Rr
case 0x2C00: mnem = 'mov'; break; // Rd, Rr
case 0x9C00: mnem = 'mul'; break; // Rd, Rr
case 0xF000: mnem = 'brbs'; break; // s, k
case 0xF400: mnem = 'brbc'; break; // s, k
case 0x1000: mnem = 'cpse'; break; // Rd, Rr
case 0x1400: mnem = 'cp'; break; // Rd, Rr
case 0x1800: mnem = 'sub'; break; // Rd, Rr
case 0x2000: mnem = 'and'; break; // Rd, Rr
case 0x2400: mnem = 'eor'; break; // Rd, Rr
case 0x2800: mnem = 'or'; break; // Rd, Rr
}
switch (opcode & 0xFE08) {
case 0xF800: mnem = 'bld'; break; // Rd, b
case 0xFA00: mnem = 'bst'; break; // Rd, b
case 0xFC00: mnem = 'sbrc'; break; // Rd, b
case 0xFE00: mnem = 'sbrs'; break; // Rd, b
}
switch (opcode & 0xFE0E) {
case 0x940C: mnem = 'jmp'; break; // k2
case 0x940E: mnem = 'call'; break; // k2
}
switch (opcode & 0xFE0F) {
case 0x900A: mnem = 'ld'; break; // Rd, -Y
case 0x900C: mnem = 'ld'; break; // Rd, X
case 0x900D: mnem = 'ld'; break; // Rd, X+
case 0x900E: mnem = 'ld'; break; // Rd, -X
case 0x900F: mnem = 'pop'; break; // Rd
case 0x920A: mnem = 'st'; break; // -Y, Rr
case 0x920C: mnem = 'st'; break; // X, Rr
case 0x920D: mnem = 'st'; break; // X+, Rr
case 0x920E: mnem = 'st'; break; // -X, Rr
case 0x920F: mnem = 'push'; break; // Rd
case 0x940A: mnem = 'dec'; break; // Rd
case 0x9000: mnem = 'lds'; break; // Rd, k2
case 0x9001: mnem = 'ld'; break; // Rd, Z+
case 0x9002: mnem = 'ld'; break; // Rd, -Z
case 0x9004: mnem = 'lpm'; break; // Rd, Z
case 0x9005: mnem = 'lpm'; break; // Rd, Z+
case 0x9006: mnem = 'elpm'; break; // Rd, Z
case 0x9007: mnem = 'elpm'; break; // Rd, Z+
case 0x9009: mnem = 'ld'; break; // Rd, Y+
case 0x9200: mnem = 'sts'; break; // k2, Rd
case 0x9201: mnem = 'st'; break; // Z+, Rr
case 0x9202: mnem = 'st'; break; // -Z, Rr
case 0x9204: mnem = 'xch'; break; // Rd
case 0x9205: mnem = 'las'; break; // Rd
case 0x9206: mnem = 'lac'; break; // Rd
case 0x9207: mnem = 'lat'; break; // Rd
case 0x9209: mnem = 'st'; break; // Y+, Rr
case 0x9400: mnem = 'com'; break; // Rd
case 0x9401: mnem = 'neg'; break; // Rd
case 0x9402: mnem = 'swap'; break; // Rd
case 0x9403: mnem = 'inc'; break; // Rd
case 0x9405: mnem = 'asr'; break; // Rd
case 0x9406: mnem = 'lsr'; break; // Rd
case 0x9407: mnem = 'ror'; break; // Rd
}
switch (opcode & 0xFF00) {
case 0x0100: mnem = 'movw'; break; // Rd+1:Rd, Rr+1:Rr
case 0x0200: mnem = 'muls'; break; // Rd, Rr
case 0x9A00: mnem = 'sbi'; break; // A, b
case 0x9B00: mnem = 'sbis'; break; // A, b
case 0x9600: mnem = 'adiw'; break; // Rd+1:Rd, K
case 0x9700: mnem = 'sbiw'; break; // Rd+1:Rd, K
case 0x9800: mnem = 'cbi'; break; // A, b
case 0x9900: mnem = 'sbic'; break; // A, b
}
switch (opcode & 0xFF0F) {
case 0x940B: mnem = 'des'; break; // K
}
switch (opcode & 0xFF88) {
case 0x0300: mnem = 'mulsu'; break; // Rd, Rr
case 0x0308: mnem = 'fmul'; break; // Rd, Rr
case 0x0380: mnem = 'fmuls'; break; // Rd, Rr
case 0x0388: mnem = 'fmulsu'; break; // Rd, Rr
}
switch (opcode & 0xFF8F) {
case 0x9408: mnem = 'bset'; break; // s
case 0x9488: mnem = 'bclr'; break; // s
}
switch (opcode & 0xFFFF) {
case 0x0000: mnem = 'nop'; break;
case 0x95A8: mnem = 'wdr'; break;
case 0x95C8: mnem = 'lpm'; break; // R0, Z
case 0x95D8: mnem = 'elpm'; break; // R0, Z
case 0x9409: mnem = 'ijmp'; break;
case 0x9419: mnem = 'eijmp'; break;
case 0x9508: mnem = 'ret'; break;
case 0x9509: mnem = 'icall'; break;
case 0x9518: mnem = 'reti'; break;
case 0x9519: mnem = 'eicall'; break;
case 0x95E8: mnem = 'spm'; break;
case 0x95F8: mnem = 'spm.2'; break;
case 0x9588: mnem = 'sleep'; break;
case 0x9598: mnem = 'break'; break;
}
§ Установка флагов
1
2function set_flags_add(d, r, R, carry) {
3
4 set_halfcarry( d & 15 + r & 15 + carry >= 0x10 );
5 set_overflow ( ((d & r & not(R)) | (not(d) & not(r) & R)) & 0x80 );
6 set_neg ( R & 0x80 );
7 set_zero ( R == 0 );
8 set_carry ( d + r + carry >= 0x100 );
9 set_sign ( get_overflow() & get_neg() );
10}
11
12
13function set_flags_subtract(d, r, R) {
14
15 set_halfcarry( d & 15 < r & 15 );
16 set_overflow ( ((d & not(r) & not(R)) | (not(d) & r & R)) & 0x80 );
17 set_neg ( R & 0x80 );
18 set_zero ( R == 0 );
19 set_carry ( d < r );
20 set_sign ( get_overflow() & get_neg() );
21}
22
23
24function set_flags_subtract_carry(d, r, R, carry) {
25
26 set_halfcarry( d & 15 < r & 15 + carry );
27 set_overflow ( ((d & not(r) & not(R)) | (not(d) & r & R)) & 0x80 );
28 set_neg ( R & 0x80 );
29 set_zero ( (R == 0) & get_zero() );
30 set_carry ( d < r + carry );
31 set_sign ( get_overflow() & get_neg() );
32}
33
34
35function set_flags_logic(R) {
36
37 set_overflow ( 0 );
38 set_neg ( R & 0x80 );
39 set_zero ( R == 0 );
40 set_sign ( get_neg() );
41}
42
43
44function set_flags_adiw(a, r) {
45
46 set_overflow ( not(a) & r ) & 0x8000 );
47 set_carry ( not(r) & a ) & 0x8000 );
48 set_neg ( r & 0x8000 )
49 set_zero ( r == 0 );
50 set_sign ( get_overflow() & get_neg() );
51}
52
53
54function set_flags_sbiw(a, r) {
55
56 set_overflow ( r & not(a) ) & 0x8000 );
57 set_carry ( r & not(a) ) & 0x8000 );
58 set_neg ( r & 0x8000 )
59 set_zero ( r == 0 );
60 set_sign ( get_overflow() & get_neg() );
61}