Система команд 8051 (MCS-51)
Система команд MCS-51 — набор инструкций ядра Intel 8051, который до сих пор выполняют AT89S52, AT89C2051 и многие современные 8-битные микроконтроллеры. Ниже — все 111 команд по группам с длиной, временем выполнения и флагами, режимы адресации, полная карта кодов операций, примеры на ассемблере и типичные ошибки.
Обновлено Редакция GAW
Система команд MCS-51 появилась вместе с микроконтроллером Intel 8051 и стала одной из самых долгоживущих в истории: те же коды операций выполняют AT89S52 и AT89C2051 от Atmel (теперь Microchip) и множество современных совместимых кристаллов. Справочник ниже составлен по документу Atmel «8051 Microcontroller Instruction Set» (0509C) и сверен с руководством Intel MCS 51 (272383-002).
Коротко
- 111 команд, 44 мнемоники, занято 255 кодов операций из 256 — свободен только A5h.
- Длина команды — 1, 2 или 3 байта; первый байт — код операции, за ним адрес, константа или смещение.
- Машинный цикл классического ядра — 12 периодов генератора; команды выполняются за 1, 2 или 4 цикла, при 12 МГц это 1, 2 или 4 мкс.
- Аккумуляторная архитектура: арифметика и логика работают с аккумулятором A, умножение и деление — с парой A и B.
- Битовый процессор: 128 бит в области 20h–2Fh и биты части SFR адресуются отдельными командами с флагом C в роли битового аккумулятора.
Регистры, которые видит программист
Аккумулятор A (в SFR — ACC, адрес E0h) — источник и приёмник большинства операций. Регистр B (F0h) нужен командам MUL и DIV, в остальном это обычная ячейка. Восемь рабочих регистров R0–R7 лежат в начале внутренней памяти данных, причём таких наборов четыре — банки с адресами 00h–07h, 08h–0Fh, 10h–17h и 18h–1Fh. Текущий банк выбирают биты RS1 и RS0 регистра PSW, после сброса включён банк 0.
16-битный указатель данных DPTR состоит из DPH (83h) и DPL (82h) и служит адресом для команд MOVX, MOVC и JMP @A+DPTR. Указатель стека SP (81h) после сброса равен 07h, стек растёт вверх и находится во внутренней памяти: PUSH сначала увеличивает SP, затем записывает байт, поэтому первый сохранённый байт попадает в ячейку 08h — регистр R0 банка 1. Если банки 1–3 нужны, SP переносят выше командой вроде MOV SP, #2Fh.
Регистр состояния PSW (D0h) хранит флаги (руководство Intel, глава 2):
| Бит | Флаг | Назначение |
|---|---|---|
| PSW.7 | CY | перенос; он же битовый аккумулятор C |
| PSW.6 | AC | вспомогательный перенос из бита 3 — для двоично-десятичной арифметики |
| PSW.5 | F0 | флаг общего назначения |
| PSW.4, PSW.3 | RS1, RS0 | выбор банка регистров |
| PSW.2 | OV | переполнение при знаковой арифметике, MUL и DIV |
| PSW.1 | — | бит пользователя |
| PSW.0 | P | чётность: 1, если в аккумуляторе нечётное число единиц; обновляется аппаратно в каждом цикле |
Флаги меняют только команды ADD, ADDC и SUBB (C, OV, AC), MUL и DIV (C сбрасывается, OV по результату), DA, RRC и RLC (C), команды с операндом C — CLR, SETB, CPL, ANL, ORL, MOV C, bit — и CJNE (C). INC, DEC, DJNZ, логические операции над байтами и пересылки флаги C, OV и AC не трогают. Запись в PSW как в обычный байт, конечно, меняет и флаги.
Режимы адресации
| Обозначение | Режим | Что адресует |
|---|---|---|
| Rn | регистровый | R0–R7 текущего банка |
| direct | прямой | 8-битный адрес: 00h–7Fh — внутреннее ОЗУ, 80h–FFh — регистры SFR |
| @Ri | косвенный | ячейка внутреннего ОЗУ по адресу из R0 или R1 (00h–FFh); у MOVX — внешняя память |
| @DPTR | косвенный | внешняя память данных по 16-битному адресу |
| #data, #data16 | непосредственный | 8- или 16-битная константа в самой команде |
| @A+DPTR, @A+PC | индексный | байт памяти программ для MOVC, адрес перехода для JMP |
| bit | битовый | бит 00h–7Fh в области 20h–2Fh или бит SFR (80h–FFh) |
| rel | относительный | смещение −128…+127 от адреса следующей команды |
| addr11 | абсолютный | адрес в пределах того же блока 2 КБ памяти программ (AJMP, ACALL) |
| addr16 | длинный | любой адрес 64 КБ памяти программ (LJMP, LCALL) |
Прямой и косвенный способы различают одно и то же значение адреса. У кристаллов с 256 байтами внутреннего ОЗУ, например 8052, старшие 128 байтов (80h–FFh) доступны только косвенно, а регистры SFR с теми же адресами — только прямо (руководство Intel, глава 1). Стек тоже обращается к памяти косвенно, поэтому может занимать старшие 128 байтов, но не пространство SFR.
Арифметика
| Команда | Операнды | Действие | Байт | Циклов | Флаги |
|---|---|---|---|---|---|
| ADD | A, Rn · A, direct · A, @Ri · A, #data | A = A + источник | 1 · 2 · 1 · 2 | 1 | C, OV, AC |
| ADDC | те же | A = A + источник + C | 1 · 2 · 1 · 2 | 1 | C, OV, AC |
| SUBB | те же | A = A − источник − C | 1 · 2 · 1 · 2 | 1 | C, OV, AC |
| INC | A · Rn · direct · @Ri | +1 без флагов | 1 · 1 · 2 · 1 | 1 | — |
| DEC | A · Rn · direct · @Ri | −1 без флагов | 1 · 1 · 2 · 1 | 1 | — |
| INC | DPTR | DPTR = DPTR + 1 | 1 | 2 | — |
| MUL | AB | B:A = A × B без знака | 1 | 4 | C = 0, OV |
| DIV | AB | A = A / B, B = остаток | 1 | 4 | C = 0, OV |
| DA | A | десятичная коррекция после ADD или ADDC | 1 | 1 | C |
Команды вычитания без заёма нет — перед первой SUBB флаг C сбрасывают командой CLR C. Уменьшить DPTR тоже нельзя: INC DPTR — единственный 16-битный инкремент. OV при сложении устанавливается, когда сумма двух положительных чисел со знаком получилась отрицательной или наоборот; у MUL — когда произведение больше 255; у DIV — при делении на ноль.
Логические операции
| Команда | Операнды | Действие | Байт | Циклов |
|---|---|---|---|---|
| ANL, ORL, XRL | A, Rn · A, direct · A, @Ri · A, #data | A = A AND / OR / XOR источник | 1 · 2 · 1 · 2 | 1 |
| ANL, ORL, XRL | direct, A | байт = байт AND / OR / XOR A | 2 | 1 |
| ANL, ORL, XRL | direct, #data | байт = байт AND / OR / XOR константа | 3 | 2 |
| CLR, CPL | A | обнулить или инвертировать A | 1 | 1 |
| RL, RR | A | циклический сдвиг A влево или вправо | 1 | 1 |
| RLC, RRC | A | сдвиг A через перенос C | 1 | 1 |
| SWAP | A | обмен тетрад A | 1 | 1 |
Логические команды флаги не меняют (кроме чётности P, которая всегда следует за аккумулятором), RLC и RRC меняют только C. Формы с адресом direct позволяют маскировать биты порта или SFR без участия аккумулятора: ANL P1, #0F0h обнуляет младшие четыре линии порта 1 одной командой.
Пересылка данных
| Команда | Операнды | Байт | Циклов |
|---|---|---|---|
| MOV A, источник | Rn · direct · @Ri · #data | 1 · 2 · 1 · 2 | 1 |
| MOV Rn, источник | A · direct · #data | 1 · 2 · 2 | 1 · 2 · 1 |
| MOV direct, источник | A · Rn · direct · @Ri · #data | 2 · 2 · 3 · 2 · 3 | 1 · 2 · 2 · 2 · 2 |
| MOV @Ri, источник | A · direct · #data | 1 · 2 · 2 | 1 · 2 · 1 |
| MOV DPTR, #data16 | загрузить 16-битную константу | 3 | 2 |
| MOVC A, @A+DPTR · @A+PC | байт из памяти программ | 1 | 2 |
| MOVX A, @Ri · A, @DPTR | чтение внешней памяти данных | 1 | 2 |
| MOVX @Ri, A · @DPTR, A | запись во внешнюю память данных | 1 | 2 |
| PUSH, POP | direct | 2 | 2 |
| XCH A, … | Rn · direct · @Ri | 1 · 2 · 1 | 1 |
| XCHD A, @Ri | обмен младших тетрад | 1 | 1 |
MOV direct, direct пересылает байт между любыми ячейками внутреннего ОЗУ и SFR, минуя аккумулятор. MOVX с адресом в R0 или R1 выставляет на порт P0 только 8 бит адреса; старшие разряды при необходимости задают через другой порт заранее, отдельной командой. В MOVC A, @A+PC к аккумулятору прибавляется адрес уже следующей команды, поэтому таблица должна начинаться не дальше 255 байтов после неё — обычно её ставят сразу за подпрограммой чтения. PUSH и POP адресуют сохраняемый байт только прямо: регистр R0 текущего банка сохраняют по его адресу, например PUSH 00h для банка 0, а аккумулятор — как PUSH ACC.
Битовые команды
| Команда | Операнды | Действие | Байт | Циклов |
|---|---|---|---|---|
| CLR, SETB, CPL | C | сбросить, установить, инвертировать перенос | 1 | 1 |
| CLR, SETB, CPL | bit | то же для любого адресуемого бита | 2 | 1 |
| ANL, ORL | C, bit · C, /bit | C = C AND / OR бит или его инверсия | 2 | 2 |
| MOV | C, bit | C = бит | 2 | 1 |
| MOV | bit, C | бит = C | 2 | 2 |
| JC, JNC | rel | переход, если C = 1 / C = 0 | 2 | 2 |
| JB, JNB | bit, rel | переход, если бит = 1 / бит = 0 | 3 | 2 |
| JBC | bit, rel | переход, если бит = 1, бит при этом сбрасывается | 3 | 2 |
Косая черта в ANL C, /bit означает, что берётся инверсия бита, сам бит не меняется. JBC удобна для флагов событий: проверка и сброс выполняются одной неделимой командой, и прерывание не может вклиниться между ними.
Переходы и подпрограммы
| Команда | Операнды | Действие | Байт | Циклов |
|---|---|---|---|---|
| ACALL, AJMP | addr11 | вызов или переход в пределах блока 2 КБ | 2 | 2 |
| LCALL, LJMP | addr16 | вызов или переход в любое место 64 КБ | 3 | 2 |
| SJMP | rel | короткий переход −128…+127 | 2 | 2 |
| JMP | @A+DPTR | переход по адресу A + DPTR | 1 | 2 |
| RET, RETI | — | возврат из подпрограммы и из прерывания | 1 | 2 |
| JZ, JNZ | rel | переход, если A = 0 / A ≠ 0 | 2 | 2 |
| CJNE | A, direct, rel · A, #data, rel · Rn, #data, rel · @Ri, #data, rel | сравнить и перейти, если не равно | 3 | 2 |
| DJNZ | Rn, rel · direct, rel | уменьшить и перейти, если не ноль | 2 · 3 | 2 |
| NOP | — | пустая операция | 1 | 1 |
У AJMP и ACALL старшие 5 бит адреса берутся из счётчика команд, 3 бита — из кода операции, остальные 8 — из второго байта: поэтому для каждой из этих команд в таблице кодов 8 разных кодов (01h, 21h … E1h и 11h, 31h … F1h). CJNE, кроме перехода, устанавливает C, если первый операнд меньше второго как беззнаковое число, — так 8051 выполняет сравнение «больше-меньше». DJNZ флаги не меняет, значение 00h переходит в FFh. RETI, в отличие от RET, ещё и снимает блокировку прерываний того же уровня приоритета; PSW она не восстанавливает — его сохраняет и восстанавливает сам обработчик.
Карта кодов операций
| Старшая цифра | x0 | x1 | x2 | x3 | x4 | x5 | x6 | x7 | x8 | x9 | xA | xB | xC | xD | xE | xF |
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| 0x | NOP 1/1 | AJMP addr11 2/2 | LJMP addr16 3/2 | RR A 1/1 | INC A 1/1 | INC direct 2/1 | INC @R0 1/1 | INC @R1 1/1 | INC R0 1/1 | INC R1 1/1 | INC R2 1/1 | INC R3 1/1 | INC R4 1/1 | INC R5 1/1 | INC R6 1/1 | INC R7 1/1 |
| 1x | JBC bit, rel 3/2 | ACALL addr11 2/2 | LCALL addr16 3/2 | RRC A 1/1 | DEC A 1/1 | DEC direct 2/1 | DEC @R0 1/1 | DEC @R1 1/1 | DEC R0 1/1 | DEC R1 1/1 | DEC R2 1/1 | DEC R3 1/1 | DEC R4 1/1 | DEC R5 1/1 | DEC R6 1/1 | DEC R7 1/1 |
| 2x | JB bit, rel 3/2 | AJMP addr11 2/2 | RET 1/2 | RL A 1/1 | ADD A, #data 2/1 | ADD A, direct 2/1 | ADD A, @R0 1/1 | ADD A, @R1 1/1 | ADD A, R0 1/1 | ADD A, R1 1/1 | ADD A, R2 1/1 | ADD A, R3 1/1 | ADD A, R4 1/1 | ADD A, R5 1/1 | ADD A, R6 1/1 | ADD A, R7 1/1 |
| 3x | JNB bit, rel 3/2 | ACALL addr11 2/2 | RETI 1/2 | RLC A 1/1 | ADDC A, #data 2/1 | ADDC A, direct 2/1 | ADDC A, @R0 1/1 | ADDC A, @R1 1/1 | ADDC A, R0 1/1 | ADDC A, R1 1/1 | ADDC A, R2 1/1 | ADDC A, R3 1/1 | ADDC A, R4 1/1 | ADDC A, R5 1/1 | ADDC A, R6 1/1 | ADDC A, R7 1/1 |
| 4x | JC rel 2/2 | AJMP addr11 2/2 | ORL direct, A 2/1 | ORL direct, #data 3/2 | ORL A, #data 2/1 | ORL A, direct 2/1 | ORL A, @R0 1/1 | ORL A, @R1 1/1 | ORL A, R0 1/1 | ORL A, R1 1/1 | ORL A, R2 1/1 | ORL A, R3 1/1 | ORL A, R4 1/1 | ORL A, R5 1/1 | ORL A, R6 1/1 | ORL A, R7 1/1 |
| 5x | JNC rel 2/2 | ACALL addr11 2/2 | ANL direct, A 2/1 | ANL direct, #data 3/2 | ANL A, #data 2/1 | ANL A, direct 2/1 | ANL A, @R0 1/1 | ANL A, @R1 1/1 | ANL A, R0 1/1 | ANL A, R1 1/1 | ANL A, R2 1/1 | ANL A, R3 1/1 | ANL A, R4 1/1 | ANL A, R5 1/1 | ANL A, R6 1/1 | ANL A, R7 1/1 |
| 6x | JZ rel 2/2 | AJMP addr11 2/2 | XRL direct, A 2/1 | XRL direct, #data 3/2 | XRL A, #data 2/1 | XRL A, direct 2/1 | XRL A, @R0 1/1 | XRL A, @R1 1/1 | XRL A, R0 1/1 | XRL A, R1 1/1 | XRL A, R2 1/1 | XRL A, R3 1/1 | XRL A, R4 1/1 | XRL A, R5 1/1 | XRL A, R6 1/1 | XRL A, R7 1/1 |
| 7x | JNZ rel 2/2 | ACALL addr11 2/2 | ORL C, bit 2/2 | JMP @A+DPTR 1/2 | MOV A, #data 2/1 | MOV direct, #data 3/2 | MOV @R0, #data 2/1 | MOV @R1, #data 2/1 | MOV R0, #data 2/1 | MOV R1, #data 2/1 | MOV R2, #data 2/1 | MOV R3, #data 2/1 | MOV R4, #data 2/1 | MOV R5, #data 2/1 | MOV R6, #data 2/1 | MOV R7, #data 2/1 |
| 8x | SJMP rel 2/2 | AJMP addr11 2/2 | ANL C, bit 2/2 | MOVC A, @A+PC 1/2 | DIV AB 1/4 | MOV direct, direct 3/2 | MOV direct, @R0 2/2 | MOV direct, @R1 2/2 | MOV direct, R0 2/2 | MOV direct, R1 2/2 | MOV direct, R2 2/2 | MOV direct, R3 2/2 | MOV direct, R4 2/2 | MOV direct, R5 2/2 | MOV direct, R6 2/2 | MOV direct, R7 2/2 |
| 9x | MOV DPTR, #data16 3/2 | ACALL addr11 2/2 | MOV bit, C 2/2 | MOVC A, @A+DPTR 1/2 | SUBB A, #data 2/1 | SUBB A, direct 2/1 | SUBB A, @R0 1/1 | SUBB A, @R1 1/1 | SUBB A, R0 1/1 | SUBB A, R1 1/1 | SUBB A, R2 1/1 | SUBB A, R3 1/1 | SUBB A, R4 1/1 | SUBB A, R5 1/1 | SUBB A, R6 1/1 | SUBB A, R7 1/1 |
| Ax | ORL C, /bit 2/2 | AJMP addr11 2/2 | MOV C, bit 2/1 | INC DPTR 1/2 | MUL AB 1/4 | A5 — | MOV @R0, direct 2/2 | MOV @R1, direct 2/2 | MOV R0, direct 2/2 | MOV R1, direct 2/2 | MOV R2, direct 2/2 | MOV R3, direct 2/2 | MOV R4, direct 2/2 | MOV R5, direct 2/2 | MOV R6, direct 2/2 | MOV R7, direct 2/2 |
| Bx | ANL C, /bit 2/2 | ACALL addr11 2/2 | CPL bit 2/1 | CPL C 1/1 | CJNE A, #data, rel 3/2 | CJNE A, direct, rel 3/2 | CJNE @R0, #data, rel 3/2 | CJNE @R1, #data, rel 3/2 | CJNE R0, #data, rel 3/2 | CJNE R1, #data, rel 3/2 | CJNE R2, #data, rel 3/2 | CJNE R3, #data, rel 3/2 | CJNE R4, #data, rel 3/2 | CJNE R5, #data, rel 3/2 | CJNE R6, #data, rel 3/2 | CJNE R7, #data, rel 3/2 |
| Cx | PUSH direct 2/2 | AJMP addr11 2/2 | CLR bit 2/1 | CLR C 1/1 | SWAP A 1/1 | XCH A, direct 2/1 | XCH A, @R0 1/1 | XCH A, @R1 1/1 | XCH A, R0 1/1 | XCH A, R1 1/1 | XCH A, R2 1/1 | XCH A, R3 1/1 | XCH A, R4 1/1 | XCH A, R5 1/1 | XCH A, R6 1/1 | XCH A, R7 1/1 |
| Dx | POP direct 2/2 | ACALL addr11 2/2 | SETB bit 2/1 | SETB C 1/1 | DA A 1/1 | DJNZ direct, rel 3/2 | XCHD A, @R0 1/1 | XCHD A, @R1 1/1 | DJNZ R0, rel 2/2 | DJNZ R1, rel 2/2 | DJNZ R2, rel 2/2 | DJNZ R3, rel 2/2 | DJNZ R4, rel 2/2 | DJNZ R5, rel 2/2 | DJNZ R6, rel 2/2 | DJNZ R7, rel 2/2 |
| Ex | MOVX A, @DPTR 1/2 | AJMP addr11 2/2 | MOVX A, @R0 1/2 | MOVX A, @R1 1/2 | CLR A 1/1 | MOV A, direct 2/1 | MOV A, @R0 1/1 | MOV A, @R1 1/1 | MOV A, R0 1/1 | MOV A, R1 1/1 | MOV A, R2 1/1 | MOV A, R3 1/1 | MOV A, R4 1/1 | MOV A, R5 1/1 | MOV A, R6 1/1 | MOV A, R7 1/1 |
| Fx | MOVX @DPTR, A 1/2 | ACALL addr11 2/2 | MOVX @R0, A 1/2 | MOVX @R1, A 1/2 | CPL A 1/1 | MOV direct, A 2/1 | MOV @R0, A 1/1 | MOV @R1, A 1/1 | MOV R0, A 1/1 | MOV R1, A 1/1 | MOV R2, A 1/1 | MOV R3, A 1/1 | MOV R4, A 1/1 | MOV R5, A 1/1 | MOV R6, A 1/1 | MOV R7, A 1/1 |
Время выполнения
Длительность команды в машинных циклах переводится во время умножением на 12 периодов генератора: при кварце 12 МГц цикл равен 1 мкс, при 11,0592 МГц — около 1,085 мкс. Простой цикл задержки:
MOV R7, #250 ; 1 cycle
WAIT: DJNZ R7, WAIT ; 2 cycles, 250 times
занимает 1 + 250 · 2 = 501 машинный цикл — 501 мкс при 12 МГц. Сама команда LCALL и возврат RET добавят ещё по 2 цикла, если задержка оформлена подпрограммой. У современных совместимых кристаллов с ускоренным ядром число тактов на команду другое — для них цикл задержки пересчитывают по таблице из даташита конкретной микросхемы.
Примеры
Сложение 16-битных чисел R1:R0 и R3:R2 с результатом в R1:R0:
MOV A, R0
ADD A, R2 ; low bytes, C = carry out
MOV R0, A
MOV A, R1
ADDC A, R3 ; high bytes plus carry
MOV R1, A ; C = 1 if the sum does not fit in 16 bits
Таблица констант в памяти программ — квадрат числа 0–7:
MOV DPTR, #SQUARES
MOVC A, @A+DPTR ; A = SQUARES[A]
; ...
SQUARES: DB 0, 1, 4, 9, 16, 25, 36, 49
Сравнение «меньше» с помощью CJNE:
CJNE A, #40, CHECK ; C = 1 if A < 40 (unsigned)
CHECK: JC BELOW ; A < 40
; A >= 40 here
Если A равно 40, CJNE не переходит, но следующая команда — та же метка CHECK, и C при этом сброшен.
Ветвление по номеру в аккумуляторе через таблицу переходов:
RL A ; AJMP takes 2 bytes: index * 2
MOV DPTR, #TABLE
JMP @A+DPTR
TABLE: AJMP CASE0
AJMP CASE1
AJMP CASE2
AJMP CASE3
Двоично-десятичное сложение:
MOV A, #29h ; BCD 29
ADD A, #14h ; binary result 3Dh
DA A ; A = 43h, that is BCD 43
Логика над битами без ветвлений — вывод P1.0 = P3.2 AND NOT F0:
MOV C, P3.2
ANL C, /F0
MOV P1.0, C
Частые ошибки
- AJMP или ACALL за пределы блока 2 КБ. Адрес назначения должен лежать в том же блоке, что и следующая команда; ассемблер выдаст ошибку, но при переносе кода её легко получить. LJMP и LCALL длиннее на байт, зато работают с любым адресом.
- SUBB без CLR C. Если флаг переноса остался от предыдущей операции, результат окажется на единицу меньше.
- Прямая адресация вместо косвенной для старших 128 байтов.
MOV 90h, #55hзаписывает в порт P1 — регистр SFR с адресом 90h, аMOV R0, #90hи затемMOV @R0, #55h— в ячейку 90h внутреннего ОЗУ кристалла с 256 байтами памяти. - Стек поверх банков регистров. После сброса SP = 07h, и стек растёт прямо в банк 1. Если используются банки 1–3 или битовая область 20h–2Fh, SP нужно перенести в начале программы.
- Чтение порта командами read-modify-write. ANL, ORL, XRL, JBC, CPL, INC, DEC, DJNZ, MOV Px.y, C, CLR Px.y и SETB Px.y, когда операнд — порт или его бит, читают защёлку порта, а не уровень на выводе (руководство Intel, глава 3). Так сделано, чтобы вывод, нагруженный, например, на базу транзистора, не читался как 0. Состояние самого вывода читают командами вроде
MOV A, P1иMOV C, P1.0. - RET вместо RETI в обработчике прерывания. Возврат произойдёт, но контроллер прерываний будет считать обработчик незавершённым, и прерывания того же и более низкого приоритета больше не придут.
- Деление на ноль. DIV AB с B = 0 устанавливает OV, а A и B после неё не определены — проверяйте OV или делитель заранее.
Память, регистры SFR, таймеры, UART и прерывания описаны в статье об архитектуре 8051, обзор семейства и отличия 8051, 8052, AT89S52 и AT89C2051 — на странице «Микроконтроллеры 8051». Для сравнения: система команд AVR разобрана на странице «Система команд AVR», а Thumb-2 ядер Cortex-M — на странице Thumb-2.
Частые вопросы
Сколько команд у 8051?
В сводной таблице Atmel 0509C 111 строк — столько вариантов команд с разными способами адресации, у них 44 мнемоники. Из 256 кодов операций занято 255, код A5h не используется. Длина команды — от 1 до 3 байтов.
Сколько длится машинный цикл 8051?
У классического ядра машинный цикл занимает 12 периодов генератора: при кварце 12 МГц это 1 мкс. Большинство команд выполняются за 1 или 2 цикла, и только MUL AB и DIV AB — за 4. У современных клонов с ускоренным ядром время выполнения другое, его берут из документации конкретного кристалла.
Чем MOVC отличается от MOVX?
MOVC читает байт из памяти программ — так достают константы и таблицы из ПЗУ. MOVX читает или пишет внешнюю память данных по адресу из DPTR (16 бит) или из R0, R1 (8 бит). Обычная MOV работает только с внутренней памятью данных и регистрами SFR.
Есть ли у 8051 команды умножения и деления?
Да: MUL AB перемножает A и B без знака, младший байт произведения остаётся в A, старший — в B, OV = 1, если результат больше 255. DIV AB делит A на B: частное в A, остаток в B. При делении на ноль OV = 1, а содержимое A и B не определено. Обе команды выполняются за 4 машинных цикла.
Как переключить банк регистров R0–R7?
Битами RS1 и RS0 регистра PSW: 00 — банк 0 (адреса 00h–07h), 01 — банк 1 (08h–0Fh), 10 — банк 2 (10h–17h), 11 — банк 3 (18h–1Fh). Например, SETB RS0 и CLR RS1 включают банк 1. Обработчику прерывания удобно выделить свой банк: тогда регистры прерванной программы не нужно сохранять в стеке.
Источники
- Atmel. 8051 Microcontroller Instruction Set (0509C, 07/06) — таблица флагов, режимы адресации, таблица 1-3 — 111 команд с байтами и периодами генератора, таблица 1-4 — коды операций, раздел 1.1 — описание каждой команды
- Intel. MCS 51 Microcontroller Family User's Manual (272383-002, февраль 1994); копия на сайте курса MIT 6.115 — глава 1 — память, банки регистров, стек; глава 2 — PSW, адреса SFR (таблица 1), система команд; глава 3 — команды read-modify-write
Нашли ошибку?
Смотрите также
- 8051 (MCS-51)Ядро MCS-51, 8051 и 8052, AT89S52, AT89C2051, система команд
- Архитектура 8051Память, SFR, машинный цикл, порты, таймеры, UART и прерывания
- Система команд AVRВсе инструкции с флагами и тактами, адресация, примеры кода
- Система команд Thumb-2Команды по группам, Operand2, флаги и условия, IT, переходы, DSP и FPU, M0
- МикроконтроллерыAVR, ARM Cortex-M, ESP32, PIC, MSP430: архитектура и выбор