Чем отличаются команды ret и reti
Перейти к содержимому

Чем отличаются команды ret и reti

Система команд микроконтроллеров AVR

Микроконтроллеры (далее — МК) серии AVR имеют от 90 до 120 команд в зависимости от модели. Здесь рассмотрены только те команды, которые использованы в нашей программе.

ADD

Синтаксис: ADD reg1, reg2

Эта команда складывает содержимое регистров reg1 и reg2, сохраняя результат в регистре reg1. Изменяет состояние флагов H, S, V, N, Z, C.

AND

Синтаксис: AND reg1, reg2

Эта команда выполняет операцию «Логическое И» между регистрами reg1 и reg2, сохраняя результат в регистре reg1. Изменяет состояние флагов S, V, N, Z.

ANDI

Синтаксис: ANDI hreg, number

Эта команда выполняет операцию «Логическое И» между содержимым старшего регистра hreg и константой number (0…255), сохраняя результат в регистре. Изменяет состояние флагов S, V, N, Z.

BRBC

Синтаксис: BRBC bit, label

Эта команда проверяет состояние бита регистра SREG ($3F) и переходит к метке label, если бит сброшен. Метка должна находиться в пределах 63 команд от команды brbc.

BRBS

Синтаксис: BRBS bit, label

Эта команда проверяет состояние бита регистра SREG ($3F) и переходит к метке label, если бит установлен. Метка должна находиться в пределах 63 команд от команды brbs.

BRCC

Синтаксис: BRCC bit, label

Эта команда проверяет флаг переноса (С) и переходит к метке label, если он сброшен.

BRCS

Синтаксис: BRCS bit, label

Эта команда проверяет флаг переноса (С) и переходит к метке label, если он установлен.

BREQ

Синтаксис: BREQ bit, label

Эта команда проверяет флаг нуля (Z) и переходит к метке label, если он установлен.

BRNE

Синтаксис: BRNE bit, label

Эта команда проверяет флаг нуля (Z) и переходит к метке label, если он сброшен.

CBI

Синтаксис: CBI ioreg, bit

Эта команда сбрасывает в 0 бит регистра ввода-вывода ioreg ($00…$1F). Номер бита определяет операнд bit.

CLR

Синтаксис: CLR reg

Эта команда сбрасывает все биты регистра reg в 0. Изменяет состояние флагов S, V, N, Z.

CP

Синтаксис: CP reg1, reg2

Эта команда сравнивает содержимое регистров reg1 и reg2 путем вычитания reg2 из reg1. Содержимое регистров не изменяется. Изменяет состояние флагов H, S, V, N, Z, C.

CPI

Синтаксис: CPI hreg, number

Эта команда сравнивает содержимое регистра hreg с константой number путем вычитания константы из регистра. Содержимое регистров не изменяется. Изменяет состояние флагов H, S, V, N, Z, C. Команда работает только с регистрами R16…R31.

DEC

Синтаксис: DEC reg

Эта команда уменьшает на единицу содержимое регистра reg, записывая результат обратно в регистр. Изменяет состояние флагов S, V, N, Z.

IN

Синтаксис: IN reg, ioreg

Эта команда пересылает содержимое регистра ввода-вывода ioreg в РОН reg.

INC

Синтаксис: INC reg

Эта команда увеличивает на единицу содержимое регистра reg, записывая результат обратно в регистр. Изменяет состояние флагов S, V, N, Z.

LD

Синтаксис: LD reg, longreg

Эта команда загружает один байт из памяти данных (адрес ячейки памяти содержится в регистре longer) в регистр reg (для модели 1200).

LDI

Синтаксис: LDI hreg, number

Эта команда загружает непосредственное значение number в старший регистр hreg (команда может работать только с регистрами R16…R31). Число number должно находиться в пределах 0…255.

LSR

Синтаксис: LSR reg

Эта команда выполняет логический сдвиг вправо содержимого регистра reg. При этом 0-й бит копируется в флаг C, 7-й бит сбрасывается в 0. Изменяет состояние флагов S, V, N, Z, C.

ORI

Синтаксис: ORI hreg, number

Эта команда выполняет операцию «Логическое ИЛИ» между содержимым старшего регистра hreg и константой number (0…255), сохраняя результат в регистре. Изменяет состояние флагов S, V, N, Z.

OUT

Синтаксис: OUT ioreg, reg

Эта команда пересылает содержимое регистра общего назначения reg в регистр ввода-вывода ioreg.

RCALL

Синтаксис: RCALL label

Эта команда вызывает подпрограмму, обозначенную меткой label, которая должна находиться в пределах 2048 команд от команды rcall (относительный вызов).

RET

Синтаксис: RET

Эта команда выполняет возврат из подпрограммы, переходя на команду, которая следует за исходной командой call.

RETI

Синтаксис: RETI

Эта команда выполняет возврат из подпрограммы и устанавливает флаг общего разрешения прерываний.

RJMP

Синтаксис: RJMP label

Относительный переход. Выполняет переход к участку программы, обозначенному меткой label, которая должна находиться в пределах 2048 от команды RJMP.

SBI

Синтаксис: SBI ioreg, bit

Эта команда устанавливает в 1 бит регистра ввода-вывода ioreg ($00…$1F). Номер бита определяет операнд bit.

SBIC

Синтаксис: SBIC ioreg, bit

Эта команда проверяет бит регистра ввода-вывода ioreg ($00…$1F) и пропускает следующую команду, если этот бит сброшен. Номер бита определяет операнд bit.

SBIS

Синтаксис: SBIS ioreg, bit

Эта команда проверяет бит регистра ввода-вывода ioreg ($00…$1F) и пропускает следующую команду, если этот бит установлен. Номер бита определяет операнд bit.

SEI

Синтаксис: SEI

Эта команда устанавливает флаг общего разрешения прерываний.

SER

Синтаксис: SER reg

Эта команда устанавливает все биты регистра reg в 1. Изменяет состояние флагов S, V, N, Z. Команда может работать только с регистрами R16…R31.

ST

Синтаксис: ST reg, longreg

Для модели 1200 эта команда сохраняет содержимое регистра reg в памяти данных (адрес ячейки памяти содержится в регистре longer), т.е. косвенно пересылает содержимое РОН reg по адресу, хранящемуся в регистре longer.

SUBI

Синтаксис: SUBI hreg, number

Вычитает из старшего регистра hreg константу number. Результат сохраняется в этом же регистре. Изменяет состояние флагов H, S, V, N, Z, C. Команда может работать только с регистрами R16…R31.

Чем отличаются команды ret и reti

Все, что необходимо начинающему и опытному программисту

Ячейки, название которых начинается с BOOT, определяют режим начальной загрузки — как я уже упоминал, в современных AVR можно изменять начальный адрес программы и расположение векторов прерываний. Данные ячейки, как и все остальные, следует оставить как есть. В том числе это касается и битов защиты программы (тех самых «предохранительных», которые здесь называются Boot Lock Bits), которые, к сожалению, настоящей защиты не дают, т. к. легко обходятся. Зато неприятностей могут доставить много, поскольку раз запрограммировав их, исправить что-то уже довольно трудно, а для любителя — почти невозможно.

ГЛАВА 6
Система команд AVR
Познакомившись в предыдущей главе с простейшими программами для AVR, мы теперь попробуем рассмотреть систему команд AVR в целом, чтобы понять, какие возможности нам предоставляются. Всего для AVR насчитывается от 90 до 133 команд (в зависимости от контроллера), и только их подробное описание, например в [2], занимает почти 70 страниц. Потому все команды, которые к тому же часто взаимозаменяемы, мы описывать не будем, для этого существуют справочники. С некоторыми из тех команд, что выпадут из рассмотрения в этой главе, мы познакомимся по ходу дела в дальнейшем. Если будете пользоваться [2], то имейте в виду, что в описаниях команд там встречается несколько мелких, но досадных опечаток (по крайней мере, так было в первом издании), и в критичных случаях нужно проверять по англоязычному фирменному оригиналу. Выборочный перечень команд с их краткой характеристикой, достаточный для составления большинства законченных программ, вы также найдете в приложении 2.

Команды передачи управления и регистр SREG
В языках высокого уровня была всего одна команда перехода на метку (GOTO), и то Дейкстра на нее набросился. А в ассемблере AVR таких команд — пруд пруди, более 30! Зачем? На самом деле без доброй половины из них, если не больше, можно обойтись во всех жизненных случаях, т. к. они в значительной степени взаимозаменяемы. Разнообразие это, если угодно, дань памяти великому программисту — для повышения читаемости программ. Мы рассмотрим только ключевые команды из этого перечня. С командами безусловного перехода rjmp и jmp мы уже познакомились достаточно подробно в предыдущей главе в связи с прерываниями, так что сразу перейдем к вызову процедур (официальный язык атмеловских руководств предпочитает консервативный термин подпрограмма — subroutine) — rcaii и call. Синтаксис у них точно такой же, как у команд безусловного перехода, и по сути это тот же самый переход по метке. И разница между этими двумя командами тоже аналогичная — call работает в пределах 64 К адресов памяти (или до 8 М адресов в соответствующем контроллере, поддерживающем такой объем адресного пространства), занимает четыре байта и выполняется за четыре цикла, a rcall годится только для МК с объемом памяти не более 8 кбайт, но занимает два байта и выполняется за три цикла. Мы в дальнейшем будем пользоваться только командой rcall.

Отличаются они от команд безусловного перехода тем, что здесь в момент перехода к процедуре контроллер автоматически сохраняет в стеке адрес текущей команды, чтобы потом знать, куда вернуться (потому длительность выполнения этих команд на такт больше, чем для простого перехода, см. далее). А как МК «узнает», когда именно нужно возвращаться? Для этого каждая процедура-подпрограмма оформляется специальным образом — не отличаясь сначала ничем от любого другого участка программного кода, обозначенного меткой, в месте возврата она должна содержать специальную команду — ret (от return — «возврат»). По этой команде МК извлекает из стека сохраненное содержимое счетчика команд и продолжает выполнение прерванной основной программы. Аналогично обрабатываются прерывания — только специальной команды, как вы знаете, там нет, вызов производится обычным переходом rjmp или jmp, но поскольку он осуществляется с определенного адреса (там, где стоит вектор прерывания), то контроллер делает то же самое — сохраняет в стеке адрес командного счетчика, на котором выполнение основной программы было грубо нарушено, начинает выполнять прерывание и ожидает команды возврата — только здесь она записывается, как reti (return interrupt) — в отличие от ret, эта команда еще и восстанавливает состояние флага прерываний i в регистре SREG.

В самой обширной группе команд передачи управления названия начинаются с букв br, от слова branch — «ветка». Это команды условного перехода, которые считаются одними из самых главных в любой системе программирования, поскольку позволяют организовывать циклы — базовое понятие программистских наук. По смыслу все эти команды сводятся к банальному if . then («если . то»). Мы будем пользоваться лишь некоторыми командами, потому что они во многом взаимозаменяемы. Смысл остальных вам будет понятен из их описания. Наиболее часто употребляется пара brne (Branch if Not Equal, «перейти, если не равно») и breq (Branch if Equal, «перейти, если равно»). Уже из смысла этих команд понятно, как они пишутся — после команды следует метка, на которую нужно перейти. Вопрос только, откуда здесь берется собственно условие? Для этого эти две команды ветвления обязательно употребляют в паре с одной из команд, устанавливающих флаг нуля z в регистре состояния SREG.

Обычно для этой цели используют команду ср (от compare— «сравнить»), которая сравнивает регистры, или cpi («сравнить с непосредственным значением»). Для понимания того, что именно при этом происходит, нужно учесть, что данные команды по сути вычитают второй операнд из первого, отличаясь от команд sub или subi только тем, что результат теряется, а операнды остаются теми же, меняются только значения соответствующих флагов регистра SREG, ИЗ которых нас интересуют в первую очередь флаг нуля z, отрицательного значения N и переноса с.

Указанные флаги устанавливаются не только в результате сравнения, но и при выполнении операций с битами или арифметических операций, когда значение результата, соответственно, становится нулевым, отрицательным или превышает диапазон 8-битового числа (255). Что означают флаги регистра SREG в целом, можно посмотреть в табл. 6.1 (на белом фоне находятся флаги, относящиеся к операциям сравнения, а также к арифметическим операциям).

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru

Справочник по командам ассемблера AVR

avr commands

Справочник по системе команд микроконтроллеров AVR основан на переводе документации от Atmel. Помимо этого сюда добавлено больше примеров из практики, в частности, примеры для ассемблера AVR GCC.

Чтобы быстро перейти к нужной команде достаточно ввести её имя. Также можно выбрать команду из списка внизу.

Справочник будет дополняться по мере появления вопросов.

Введите имя команды в поле выше

Логические операции

Мнемоника Описание Операция Флаги
AND Rd, Rr Логическое «И» двух регистров Rd ← Rd and Rr Z, N, V
ANDI Rd, K Логическое «И регистра и константы Rd ← Rd and K Z, N, V
EOR Rd, Rr Исключающее «ИЛИ» двух регистров Rd ← Rd xor Rr Z, N, V
OR Rd, Rr Логическое «ИЛИ» двух регистров Rd ← Rd or Rr Z, N, V
ORI Rd, K Логическое «ИЛИ» регистра и константы Rd ← Rd or K Z, N, V
COM Rd Перевод в обратный код Rd ← 0xFF — Rd Z, C, N, V
NEG Rd Перевод в дополнительный код Rd ← 0 — Rd Z, C, N, V, H
CLR Rd Очистка регистра Rd ← Rd xor Rd Z, N, V
SER Rd Установка всех разрядов регистра Rd ← 0xFF
TST Rd Проверка регистра на отрицательное (нулевое) значение Rd ← Rd and Rd Z, N, V

Арифметические операции

Мнемоника Описание Операция Флаги
ADD Rd, Rr Сложение двух регистров Rd ← Rd + Rr Z, C, N, V, H
ADC Rd, Rr Сложение двух регистров с переносом Rd ← Rd + Rr + С Z, C, N, V, H
SUB Rd, Rr Вычитание двух регистров Rd ← Rd — Rr Z, C, N, V, H
SBC Rd, Rr Вычитание двух регистров с заёмом Rd ← Rd — Rr — С Z, C, N, V, H
ADIW Rd, K Сложение регистровой пары с константой R(d+1):Rd ← R(d+1):Rd + K Z, C, N, V, S
SBIW Rd, K Вычитание константы из регистровой пары R(d+1):Rdl ← R(d+1):Rd — K Z, C, N, V, S
SUBI Rd, K Вычитание константы из регистра Rd ← Rd — K Z, C, N, V, H
SBCI Rd, K Вычитание константы из регистра с заёмом Rd ← Rd — K — С Z, C, N, V, H
INC Rd Инкремент регистра Rd ← Rd + 1 Z, N, V
DEC Rd Декремент регистра Rd ← Rd – 1 Z, N, V
MUL Rd, Rr Умножение чисел без знака R1:R0 ← Rd * Rr Z, C
MULS Rd, Rr Умножение чисел со знаком R1:R0 ← Rd * Rr Z, C
MULSU Rd, Rr Умножение числа со знаком с числом без знака R1:R0 ← Rd * Rr Z, C
FMUL Rd, Rr Умножение дробных чисел без знака R1:R0 ← (Rd * Rr)

Z, C
FMULS Rd, Rr Умножение дробных чисел со знаком R1:R0 ← (Rd * Rr)

Z, C
FMULSU Rd, Rr Умножение дробного числа со знаком с числом без знака R1:R0 ← (Rd * Rr)

Z, C

Битовые операции

Мнемоника Описание Операция Флаги
CBR Rd, K Очистка разрядов регистра Rd ← Rd and (0FFH – K) Z, N, V
SBR Rd, K Установка разрядов регистра Rd ← Rd or K Z, N, V
CBI P, b Сброс разряда I/O-регистра P.b ← 0
SBI P, b Установка разряда I/O-регистра P.b ← 1
BCLR s Сброс флага SREG SREG.s ← 0 SREG.s
BSET s Установка флага SREG SREG.s ← 1 SREG.s
BLD Rd, b Загрузка разряда регистра из флага T Rd.b ← T
BST Rr, b Запись разряда регистра во флаг T T ← Rd.b T
CLC Сброс флага переноса C ← 0 C
SEC Установка флага переноса C ← 1 C
CLN Сброс флага отрицательного числа N ← 0 N
SEN Установка флага отрицательного числа N ← 1 N
CLZ Сброс флага нуля Z ← 0 Z
SEZ Установка флага нуля Z ← 1 Z
CLI Общий запрет прерываний I ← 0 I
SEI Общее разрешение прерываний I ← 1 I
CLS Сброс флага знака S ← 0 S
SES Установка флага знака S ← 1 S
CLV Сброс флага переполнения дополнительного кода V ← 0 V
SEV Установка флага переполнения дополнительного кода V ← 1 V
CLT Сброс пользовательского флага T T ← 0 T
SET Установка пользовательского флага T T ← 1 T
CLH Сброс флага половинного переноса H ← 0 H
SEH Установка флага половинного переноса H ← 1 H

Операции сравнения

Мнемоника Описание Операция Флаги
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 – K) Z, N, V, C, H
CPSE Rd, Rr Сравнение регистров и пропуск следующей команды если они равны Если (Rd = Rr) PC ← PC + 2 (или 3)

Операции сдвига

Мнемоника Описание Операция Флаги
ASR Rd Арифметический сдвиг вправо Rd(i) ← Rd(i+1) (n=0..6), C ← Rd(0) Z, C, N, V
LSL Rd Логический сдвиг влево Rd(i+1) ← Rd(i), Rd(0) ← 0, C ← Rd(7) Z, C, N, V
LSR Rd Логический сдвиг вправо Rd(i) ← Rd(i+1), Rd(7) ← 0, C ← Rd(0) Z, C, N, V
ROL Rd Сдвиг влево через перенос Rd(i+1) ← Rd(i), Rd(0) ← C, C ← Rd(7) Z, C, N, V
ROR Rd Сдвиг вправо через перенос Rd(i) ← Rd(i+1), Rd(7) ← C, C ← Rd(0) Z, C, N, V
SWAP Rd Обмен местами тетрад Rd(3..0) ↔ Rd(7..4)

Операции пересылки данных

Мнемоника Описание Операция Флаги
MOV Rd, Rr Пересылка между регистрами Rd ← Rr
MOVW Rd, Rr Пересылка между парами регистров R(d +1):Rd ← R(r+1):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 Косвенное чтение со смещением Rd ← [Y+q]
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+q]
LDS Rd, A Непосредственное чтение из ОЗУ Rd ← [A]
ST X, Rr Косвенная запись [X] ← Rr
ST X+, Rr Косвенная запись с пост-инкрементом [X] ← Rr, X ← X + 1
ST -X, Rr Косвенная запись с пред-декрементом X ← X — 1, [X] ← Rr
ST Y, Rr Косвенная запись [Y] ← Rr
ST Y+, Rr Косвенная запись с пост-инкрементом [Y] ← Rr, Y ← Y + 1
ST -Y, Rr Косвенная запись с пред-декрементом Y ← Y — 1, [Y] ← Rr
STD Y+q, Rr Косвенная запись со смещением [Y+q] ← Rr
ST Z, Rr Косвенная запись [Z] ← Rr
ST Z+, Rr Косвенная запись с пост-инкрементом [Z] ← Rr, Z ← Z + 1
ST -Z, Rr Косвенная запись с пред-декрементом Z ← Z — 1, [Z] ← Rr
STD Z+q, Rr Косвенная запись со смещением [Z+q] ← Rr
STS A, Rr Непосредственная запись в ОЗУ [A] ← Rr
LPM Загрузка данных из памяти программы R0 ←

LPM Rd, Z Загрузка данных из памяти программы в регистр Rd ←

LPM Rd, Z+ Загрузка данных из памяти программы с пост-инкрементом Z Rd ← , Z ← Z + 1
ELPM Расширенная загрузка данных из памяти программы R0 ←

ELPM Rd, Z Расширенная загрузка данных из памяти программы в регистр Rd ←

ELPM Rd, Z+ Расширенная загрузка данных из памяти программы с пост-инкрементом Z Rd ← , Z ← Z + 1
SPM Запись в программную память ← R1:R0
IN Rd, P Пересылка из I/O-регистра в регистр Rd ← P
OUT P, Rr Пересылка из регистра в I/O-регистр P ← Rr
PUSH Rr Сохранение регистра в стеке STACK ← Rr
POP Rd Извлечение регистра из стека Rd ← STACK

Безусловные переходы

Мнемоника Описание Операция Флаги
RJMP A Относительный безусловный переход PC ← PC + A + 1
JMP A Длинный безусловный переход PC ← A
IJMP Непрямой безусловный переход PC ← Z
EIJMP Расширенный непрямой безусловный переход PC ← Z:EIND
RCALL A Относительный вызов подпрограммы PC ← PC + A + 1
CALL A Длинный вызов подпрограммы PC ← A
ICALL Непрямой вызов подпрограммы PC ← Z
EICALL Расширенный непрямой вызов подпрограммы PC ← Z:EIND
RET Возврат из подпрограммы PC ← STACK
RETI Возврат из подпрограммы обработки прерываний PC ← STACK I

Условные переходы

Все команды этой группы выполняют переход (PC ← PC + A + 1) при разных условиях.

Мнемоника Описание Условие Флаги
BRBC s, A Переход если флаг S сброшен Если SREG(S) = 0
BRBS s, A Переход если флаг S установлен Если SREG(S) = 1
BRCS A Переход по переносу Если C = 1
BRCC A Переход если нет переноса Если C = 0
BREQ A Переход если равно Если Z = 1
BRNE A Переход если не равно Если Z = 0
BRSH A Переход если больше или равно Если C = 0
BRLO A Переход если меньше Если C = 1
BRMI A Переход если отрицательное значение Если N = 1
BRPL A Переход если положительное значение Если N = 0
BRGE A Переход если больше или равно (со знаком) Если (N и V) = 0
BRLT A Переход если меньше (со знаком) Если (N или V) = 1
BRHS A Переход по половинному переносу Если H = 1
BRHC A Переход если нет половинного переноса Если H = 0
BRTS A Переход если флаг T установлен Если T = 1
BRTC A Переход если флаг T сброшен Если T = 0
BRVS A Переход по переполнению дополнительного кода Если V = 1
BRVC A Переход если нет переполнения дополнительного кода Если V = 0
BRID A Переход если прерывания запрещены Если I = 0
BRIE A Переход если прерывания разрешены Если I = 1
SBRC Rd, K Пропустить следующую команду если бит в регистре очищен Если Rd[K] = 0
SBRS Rd, K Пропустить следующую команду если бит в регистре установлен Если Rd[K] = 1
SBIC A, b Пропустить следующую команду если бит в регистре ввода/вывода очищен Если I/O(A, b) = 0
SBIS A, b Пропустить следующую команду если бит в регистре ввода/вывода установлен Если I/O(A, b) = 1

Управление устройством

Мнемоника Описание Операция Флаги
NOP Нет операции
SLEEP Переход в «спящий» режим
WDR Сброс сторожевого таймера
BREAK Приостановка программы (используется отладчиком)

СИСТЕМА КОМАНД МИКРОКОНТРОЛЛЕРОВ СЕМЕЙСТВА MCS51

3.4 Инструкции со специфицированными регистрами

3.5. Непосредственная адресация

3.6. Индексная адресация

4. Арифметические инструкции

5. Логические инструкции

6. Перемещение данных

6.1. Внутренняя память

6.2. Внешняя память данных

6.3. Таблицы обращения к памяти программ

7. Булевы инструкции

8. Инструкции переходов

ИЗУЧЕНИЕ СИСТЕМЫ КОМАНД МИКРОКОНТРОЛЛЕРОВ СЕМЕЙСТВА MCS51

Цель работы

Задание и порядок выполнения работы

Оформление отчета

ПРИЛОЖЕНИЕ

СИСТЕМА КОМАНД МИКРОКОНТРОЛЛЕРОВ СЕМЕЙСТВА MCS51

1. Набор инструкций

Все типы микроконтроллеров семейства MCS51 выполняют один и тот же набор инструкций. Этот набор оптимизирован для 8-битовых приложений, он обеспечивает разнообразные быстрые режимы адресации к резидентной памяти данных и упрощенные байтовые операции с небольшими структурами данных. Набор инструкций поддерживает однобитовые переменные как отдельный тип данных, позволяя прямые битовые манипуляции в управляющих и логических системах, требующих булеву обработку.

Следующий обзор набора инструкций дает краткое описание использования некоторых из них.

2. Слово состояния программы

Слово состояния программы – Program Status Word (PSW) содержит статусные биты (флаги), которые отражают текущее состояние процессора. Регистр PSW размещается в адресном пространстве резидентной памяти для функциональных регистров – Special Function Register (SFR). Он содержит биты переноса (C), дополнительного переноса (AC) для двоично-десятичных операций, флаг (F0), определяемый пользователем, два бита для выбора банка регистров (RS1, RS0), флаг переполнения (OV) и бит четности (P).

Формат слова состояния программы

табл

Бит переноса дополнительно к обслуживанию арифметических операций используется как «аккумулятор» для множества булевых операций. Биты RS0 и RS1 выбирают один из четырех банков регистров. Множество инструкций ссылается на них как на R0 – R7.

Биты RS0 и RS1 выбирают один из четырех банков регистров. Множество инструкций ссылается на них как на R0 — R7.

Бит переполнения определяет значимость числа. Он устанавливается, если результат операции не может быть размещен в аккумуляторе или 8-ой разряд рассматриваться как знаковый.

Бит четности отражает количество 1 в аккумуляторе: Р=1, если аккумулятор содержит нечетное число единиц, и Р=0, если он содержит четное число единиц. Таким образом, число единиц в аккумуляторе плюс Р – всегда четное.

Один бит в PSW не определен, и он может использоваться как флаг общего назначения.

3. Режимы адресации

3.1. Прямая адресация

При прямой адресации операнд в инструкции специфицирован 8-битовым адресом. Только данные резидентной RAM или SFR могут адресоваться прямо.

3.2. Косвенная адресация

При косвенной адресации инструкция специфицирует регистр, который содержит адрес операнда. Косвенно адресовано может быть как внутренняя, так и внешняя RAM. Регистром для 8-битовых адресов может быть или указатель стека, или R0, или R1 выбранного банка регистров. Регистром для 16-битовых адресов может быть только регистр указателя 16-битовых данных DPTR.

3.3. Регистровая адресация

Банки регистров, содержащие регистры R0 – R7, могут быть доступны инструкциям, чьи коды операций имеют 3 бита для спецификации регистра. Инструкции, имеющие доступ к регистрам, делают код более эффективным, так как при этом отсутствует адресный байт. При выполнении инструкции доступен один из восьми регистров в выбранном банке, который выбирается из четырех возможных двумя битами PSW.

3.4. Инструкции со специфицированными регистрами

Некоторые инструкции используют определенные регистры. Например, они оперируют с аккумулятором, поэтому им не нужен какой-либо байт для адресации данных. В этих случаях код операции указывает на нужный регистр. Инструкции, которые ссылаются на аккумулятор А, ассемблируются как код операции со специфицированным аккумулятором.

3.5. Непосредственная адресация

Код операции может содержать в качестве операнда константу. Например, MOV A,#100 загружает аккумулятор десятичным числом 100. То же число может быть в шестнадцатеричном формате – 64H.

3.6. Индексная адресация

Память программ может быть доступна только через индексную адресацию. Этот режим адресации предназначен для табличного обращения к памяти программ. 16-битовый базовый регистр (либо DPTR, либо программный счетчик РС) указывает на базу таблицы, а аккумулятор задает точку входа в нее. Входной адрес в память программ формируется добавлением данных аккумулятора к базовому адресу.

Другой тип индексной адресации используется в инструкциях передачи управления. В этом случае адрес назначения передачи управления вычисляется как сумма базового указателя и содержимого аккумулятора.

4. Арифметические инструкции

Арифметические инструкции приведены в табл. 1. В таблице указаны режимы адресации, которые могут использоваться с любой инструкцией, заменяя операнд byte. Например, инструкция ADD A,byte может быть записана в следующем виде:

ADD A,7FH (прямая адресация) ADD A,@R0 (косвенная адресация) ADD A,R7 (регистровая адресация) ADD A,#127 (непосредственная адресация)

Табл. 1. Арифметические инструкции

табл1

Предполагая, что частота системного генератора 12 МГц, один машинный цикл в режиме совместимости выполняется за 1 мкс. Все арифметические операции выполняются за 1 мкс кроме инструкции INC DPTR, которая выполняется за 2 мкс, а операции умножения и деления – за 4 мкс.

Следует отметить, что любой байт резидентной памяти данных может быть инкрементирован или декрементирован без использования аккумулятора. Инструкция INC DPTR оперирует с 16-битовым указателем данных. Указатель данных генерирует 16-битовые адреса для внешней памяти, таким образом, возможность инкрементирования в 16-битовой операции является полезной особенностью.

Инструкция MUL AB умножает данные в аккумуляторе на данные в регистре В и помещает результат в регистре В и аккумуляторе.

Инструкция DIV AB делит данные в аккумуляторе на данные в регистре В и размещает 8-битовую целую часть результата в аккумуляторе, а остаток – в регистре В.

Примечание: Инструкция DIV AB использует в программе арифметического деления обычную конверсию и операции сдвига. Операции сдвига выполняют деление на 2 n сдвигом на n бит вправо. При использовании операции деления, сдвиг выполняется за 4 мкс, а сдвинутые биты размещаются в регистре В.

Инструкция DA A предназначена для двоично-десятичных операций. В двоично-десятичной арифметике после инструкций ADD и ADDC всегда необходимо выполнять операцию DA A, чтобы результат был также в двоично-десятичном коде. Заметим, что DA A не конвертирует двоичное число в двоично-десятичное число. Операция DA A дает значащий результат только как следующий шаг в дополнение операции с двумя двоично-десятичными байтами.

5. Логические инструкции

Логические инструкции приведены в табл. 2. Инструкции булевых операций (AND, OR, исключающее OR, NOT), выполняют их побитно. Таким образом, если аккумулятор содержит 00110101B, а byte содержит 01010011B, то после выполнения операции ANL A,byte в аккумуляторе будет находиться результат 00010001B.

В табл. 2 также даны режимы адресаций, которые дают доступ к операнду byte.

Таким образом, инструкция ANL A,byte может иметь следующие формы:

ANL A,7FH (прямая адресация) ANL A,@R1 (косвенная адресация) ANL A,R6 (регистровая адресация) ANL A,#53H (непосредственная адресация)

Табл. 2. Логические инструкции

табл2

Все логические инструкции, которые используют аккумулятор, выполняются за 1 мкс (при 12 МГц тактовой частоте в режиме совместимости). Другие выполняются за 2 мкс.

Заметим, что булевы операции могут выполняться с любым байтом в резидентной памяти данных или в пространстве SFR без аккумулятора, используя прямую адресацию.

Инструкция XRL byte,#data, например, дает возможность быстро и просто инвертировать биты порта:

Циклические инструкции сдвигают аккумулятор на один бит. Для левой ротации старший бит сдвигается в младший бит, для правой ротации младший бит – в старший.

Инструкция SWAP A обменивает старший и младший полубайты в аккумуляторе. Этот обмен используется в двоично-десятичной арифметике. Например, если аккумулятор содержит двоичное число меньше 100, следующий код быстро конвертирует его в двоично-десятичное число:

Деление на 10 дает цифру десятков в младшем полубайте аккумулятора, а цифру единиц в регистре В. Инструкции SWAP и ADD перемещают цифру десятков в старшую половину аккумулятора, а цифру единиц в младшую.

6. Перемещение данных

6.1. Внутренняя память

В табл. 3 приведены инструкции и соответствующие режимы адресаций, используемые для перемещения данных во внутренней памяти. С 12 МГц тактовой частотой все эти инструкции выполняются в режиме совместимости за 1 мкс или 2 мкс. Инструкция MOV dest,src позволяет передачу между любыми двумя ячейками, размещенными во внутренней RAM или SFR, без использования аккумулятора.

Заметим, что в микроконтроллере стек размещен во внутренней памяти и «растет» вверх. Инструкция PUSH прежде инкрементирует указатель стека SP, а затем копирует байт в стек. Инструкции PUSH и POP используют только прямую адресацию для идентификации байта, который должен быть сохранен или восстановлен, но сам стек доступен посредством косвенной адресацией с использованием регистра SP. Это означает, что стек может превысить 128 байт, но не в пространство SFR. В контроллерах, где нет пространства выше 128 байт, если SP устанавливается больше 128, загружаемые байты становятся потерянными, а восстанавливаемые – неопределенными.

Табл. 3. Инструкции перемещения данных, которым доступна внутренняя память

табл3

Инструкции передачи данных включают 16-битовую MOV, которая может инициализировать указатель данных DPTR для табличного обращения к памяти программ или для доступа к внешней памяти данных. Инструкция XCH A,byte обменивает данные между аккумулятором и адресованным байтом. Инструкция XCHD A,@Ri подобна предыдущей, но только обмениваются младшие полубайты.

В табл. 4 изображен простой код, который выполняет сдвиг вправо на один разряд двоично-десятичного числа, используя инструкцию XCHD.

Табл. 4. Сдвиг двоично-десятичного числа на один разряд вправо

табл4

В этом примере указатели R1 и R0 указывают на два байта, содержащие последние четыре разряда двоично-десятичного числа. Затем цикл переходит на последний байт с адресом 2ЕН, где находятся последние два разряда сдвигаемого числа. Указатели декрементируются, и цикл повторяется для адреса 2DH.

Цикл выполняется от LOOP до CJNE для R1 = 2EH, 2DH, 2CH и 2BH. В этой точке разряд, который первоначально был сдвинут вправо, переместиться в ячейку с адресом 2AH. Так как эта ячейка должна быть слева с нулями, потерянный разряд перемещается в аккумулятор.

Примечание: Инструкция CJNE (Сравнение и переход, если не равно), управляющая циклом, будет описана позже.

6.2. Внешняя память данных

Табл. 5 содержит инструкции перемещения данных, которые осуществляют доступ к внешней памяти данных. В этом случае может применена только косвенная адресация. Для однобайтовой адресации используется @Ri, где Ri может быть R0 или R1 из выбранного банка регистров, для двухбайтовой адресации — @DPTR. Неудобство использования 16-битовой адресации при подключении нескольких Кбайт внешней памяти в том, что 16-битовые адреса используют все 8 бит порта Р2, как у адресной шины. Тогда как 8-битовые адреса позволяют использовать те же несколько Кбайт памяти без жертвования всем портом Р2, используя только его часть для указания страниц памяти по 256 байт. Все эти инструкции выполняются в режиме совместимости за 2 мкс при 12 МГц тактовой частоте.

Табл. 5. Инструкции перемещения данных, осуществляющие доступ к внешней памяти данных

табл5

Заметим, что во всех обращениях к внешней памяти данных аккумулятор используется либо как цель, либо как источник. Стробы чтения и записи для внешней памяти активируются только в течение выполнения инструкции MOVX. Нормально, эти сигналы не активны и, если инструкция не выполняется, то не используются вовсе, и их выводы доступны как внешние линии ввода-вывода.

6.3. Таблицы обращения к памяти программ

Табл. 6 показывает две инструкции, которые пригодны для чтения таблиц доступа к памяти программ. Так как эти инструкции осуществляют доступ к памяти программ, таблицы могут только читаться и не могут обновляться. Мнемоникой инструкций является MOVC (move constant). Если обращаются к таблице во внешней памяти программ, то генерируется строб чтения PSEN.

Табл. 6. Инструкции чтения таблиц обращения к памяти

табл6

Первая инструкция MOVC в табл. 6 может работать с таблицей, имеющей до 256 входов с номерами от 0 до 255. Номер используемого входа загружается в аккумулятор, а указатель данных задает точку, указывающую на начало таблицы. Поэтому следующая инструкция копирует содержимое из нужной ячейки таблицы в аккумулятор:

Другая инструкция MOVC работает подобным образом, используя в этом случае в качестве базы таблицы программный счетчик PC, а через таблицу обращаются к подпрограммам. Вначале в аккумулятор загружается номер нужного входа, а затем вызывается подпрограмма.

Подпрограмма TABLE должна выглядеть, как в следующем примере:

Сама таблица непосредственно следует после инструкции RET (return) в памяти программ. Этот тип таблицы может иметь до 255 входов, пронумерованных от 1 до 255. Номер 0 может не использоваться, так как в это время выполняется инструкция MOVC и PC содержит адрес инструкции RET. Входом, имеющий номер 0 будет сам код операции RET.

7. Булевы инструкции

Микроконтроллеры MCS51 имеют булевый (битовый) процессор. Внутренняя память данных RAM содержит 128 адресуемых бит от 00 до 7FH в пространстве адресов байт от 20Н до 2FH, и пространство регистров специальных функций SFR также поддерживает битовую адресацию. Все линии порта тоже побитно адресуемые, и каждая из них может быть использована как отдельный однобитовый порт. Инструкции, обращающиеся к битам, – не только условные переходы, но и инструкции перемещения, установки, очистки, инвертирования, OR и AND.

Табл. 7. Булевы инструкции

табл7

Набор инструкций булева процессора показан в табл. 7. Все битовые обращения имеют прямую адресацию. Адреса бит от 00H до 7FH находятся в младшем 128 битовом пространстве, а с 80H до FFH – в пространстве SFR.

Следующий пример показывает, как легко внутренний флаг может быть передан в вывод порта.

В этом примере FLAG является именем любого адресуемого бита в 128 битовом пространстве или SFR. Линия ввода-вывода (младший бит порта Р1 в данном случае) устанавливается или очищается в зависимости от значения бита флага, который может быть или 1, или 0.

Бит переноса в PSW используется в качестве однобитового аккумулятора булева процессора. Битовые инструкции, которые ссылаются на бит переноса С, ассемблируются как инструкции специфицированные переносом (CLR C и т.п.). Бит переноса может адресоваться прямо, так как он размещается в регистре PSW, который является бит адресуемым. Булевы инструкции включают операции ANL и ORL, но не XRL (исключающее OR). Операция XRL реализуется в программном обеспечении просто. Предположим, например, что приложению требуется выполнить исключающее OR с двумя битами: C = bit1 .XRL. bit2

Программа для этого должна быть следующего вида:

Вначале bit1 перемещается в С. Если bit2 = 0, тогда С содержит правильный результат. Это означает, что bit1 .XRL. bit2 = bit1, если bit2= 0. С другой стороны, если bit2 = 1, С тогда содержит дополнение правильного результата. Поэтому для выполнения операции С необходимо инвертировать (CPL C). Эта программа использует инструкцию JNB, одну из серии бит-тестируемых инструкций, которая выполняет переход, если адресуемый бит установлен (JC, JB, JBC), или если адресуемый бит не установлен (JNC, JNB). В вышеописанном случае тестируется bit2, и если bit2 = 0, инструкция CPL C пропускается.

Другая тестируемая инструкция JBC выполняет переход, если бит установлен, а затем бит очищается. Таким образом, флаг может быть протестирован и очищен в одной операции.

Все биты в PSW адресуются прямо, поэтому бит четности или флаг общего назначения также используются в бит-тестируемых инструкциях.

Адрес назначения для этих переходов специфицируется для ассемблера либо меткой, либо конкретным адресом в памяти программ. Однако при ассемблировании он заменяется байтом относительного смещения. Если выполняется переход, то этот байт со знаком (в арифметическом дополнении) прибавляется к содержимому программного счетчика PC. Диапазон перехода находится в пределах от -128 до +127 байт памяти программ относительно первого байта, следующего после инструкции.

8. Инструкции переходов

В табл. 8 показаны инструкции безусловных переходов. В таблице указана одна инструкция JMP addr, но фактически их три: SJMP, LJMP и AJMP, которые различаются форматом адреса назначения. JMP является основной мнемоникой, которой может воспользоваться программист, когда он не заботится о том, каким образом адрес перехода будет закодирован. Инструкция SJMP кодирует адрес назначения с относительным смещением, как показано выше. Инструкция имеет размер в 2 байта, включая код операции и байт относительного смещения. Инструкция LJMP кодирует адрес назначения как 16-битовую константу. Инструкция имеет размер в 3 байта, включая код операции и двухбайтовый адрес. Адрес назначения может быть в любом месте 64К пространства памяти программ. Инструкция AJMP кодирует адрес назначения как 11-битовую константу. Инструкция имеет размер в 2 байта, включая код операции, который содержит 3 бита 11-битового адреса, и следующий байт, содержащий младшие 8 бит адреса назначения. Когда выполняется инструкция, эти 11 бит просто заменяют младшие 11 бит регистра PC. Старшие 5 бит остаются теми же самыми. Таким образом, адрес назначения должен быть в некотором блоке размером 2К, следующем после инструкции AJMP.

Табл. 8. Безусловные переходы

табл8

Во всех случаях программист специфицирует для ассемблера адрес назначения в виде метки или 16-битовой константы. Ассемблер переводит адрес назначения в нужный формат для данной инструкции. Если требуемый инструкцией формат не поддерживает специфицированный адрес назначения, то в листинге появится сообщение «Destination out of range» (Назначение вне области).

Инструкция JMP @A+DPTR поддерживает вычисляемые переходы. Адрес назначения вычисляется во время выполнения инструкции как сумма 16-битового регистра DPTR и аккумулятора. Обычно DPTR загружается адресом таблицы переходов, а аккумулятор является индексом в таблице. Например, если требуется 5 вариантов перехода, то в аккумулятор загружаются целые числа от 0 до 4. Программа может иметь следующий вид:

Инструкция RL A конвертирует номер индекса (0 – 4) в четное число в диапазоне от 0 до 8, так как каждый вход в таблицу переходов разделен 2 байтами, как показано в следующем примере:

JUMP_TABLE: AJMP CASE_0

AJMP CASE_1

AJMP CASE_2

AJMP CASE_3

AJMP CASE_4

Табл. 8 показывает только одну инструкцию CALL addr, но есть еще две инструкции LCALL и ACALL, которые отличаются форматом определения адреса подпрограммы. Основная мнемоника CALL используется программистом, если его не заботит, каким образом кодируется адрес. Инструкция LCALL использует 16-битовый формат адреса, и подпрограмма может находиться в любом месте 64К пространстве памяти программ. Инструкция ACALL использует 11-битовый формат и подпрограмма должна быть в 2К блоке, следующем после инструкции ACALL. В любом случае программист специфицирует адрес подпрограммы для ассемблера или как метку, или как 16-битовую константу. Ассемблер сформирует адрес в правильном формате для данной инструкции.

Подпрограммы должны заканчиваться инструкцией RET, которая возвращает выполнение программы к инструкции, следующей после CALL. Инструкция RETI используется для возврата из подпрограммы обслуживания прерывания. Отличие между RET и RETI лишь в том, что RETI сообщает системе управления прерыванием об окончании обслуживания прерывания. Если прерывания нет во время выполнения RETI, то тогда RETI функционально идентична RET.

В табл. 9 приведен список условных переходов. Все они осуществляют переход на определенный адрес назначения через относительное смещение и, таким образом, ограничены областью от – 128 до +127 байт, следующей после инструкции условного перехода. Однако пользователь специфицирует ассемблеру нужный адрес назначения тем же образом, что и для других переходов: меткой или 16-битовой константой.

Табл. 9. Условные переходы

табл9

В PSW бит Zero отсутствует. Для определения этого условия инструкции JZ и JNZ тестируют аккумулятор. Инструкция DJNZ (Decrement and Jump if Not Zero – декремент и переход, если не ноль) является управляющей для циклов. Чтобы выполнить цикл N раз, надо загрузить счетчик числом N и закончить цикл DJNZ, передающим управление в начало цикла, как показано ниже для N = 10:

Инструкция CJNE (Compare and Jump if Not Equal – сравнение и переход, если не ноль) может также использоваться для управления циклом, как показано в табл. 2.4. Два байта специфицируются в поле операндов инструкции. Переход выполняется только, если два байта не равны. В примере два байта были данными в регистре R1 и константа 2AH. Начальное значение содержимого R1 было 2EH. Каждый раз при выполнении цикла R1 декрементируется, и цикл продолжается до тех пор, пока оно не станет равным 2AH.

Другое применение этой инструкции для сравнений «больше, чем», «меньше, чем». Два байта в поле операндов берутся как беззнаковые целые числа. Если первое меньше второго, тогда бит переноса Carry устанавливается в 1. Если первый больше второго, или равен, то бит переноса очищается.

Copyright © Кафедра Электрофизических установок МИФИ, 2016 — 2021

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *