Команды передачи управления
Все команды группы передачи управления приведены в табл.3. Микроконтроллеры AVR могут содержать до 4-х разновидностей команды безусловного перехода. Команды такого типа модифицируют
содержимое программного счётчика, после чего программа продолжает выполняться с нового места (адреса перехода). Безусловный переход в памяти программ происходит не зависимо от каких либо условий, флагов программы и т.д.
Инструкция rjmp k (Относительный безусловный переход) позволяет осуществить переход в диапазоне +2047…-2047 слов в памяти программ от места где она расположена. Адрес перехода при этом зависит от текущего значения программного счётчика и вычисляется как смещение PC+1+k.
Команда ijmp (Косвенный безусловный переход) производит переход в памяти программ в пределах 0…65535 слов по адресу, находящемуся в индексном регистре Z. В этом случае адрес перехода является переменной величиной доступной из программы. Это даёт возможность легко реализовать процедуру ветвления, когда в зависимости от условий должен быть выполнен тот или иной фрагмент кода.
В моделях с объёмом памяти программ 256 кб доступна также команда eijmp (Расширенный безусловный косвенный переход). Она использует 3-байтовый указатель адреса EIND:ZH:ZL. В регистре EIND из пространства РВВ находится 17-тый бит адреса, а переход осуществляется в пределах 0…131071 слов.
Команда jmp k (Абсолютный безусловный переход) — переход по адресу k в любую точку из любого места программы. Абсолютный адрес перехода находится в коде операции, а команда занимает 2 слова (4 байта) и выполняется в течении 3-х машинных циклов.
При использовании команд передачи управления в качестве параметров обычно используют метки, в место которых после компоновки программы будут подставлены реальные адреса (смещения относительно адреса):
Другим типом команд являются вызовы подпрограмм. Существуют следующие их разновидности: rcall k (Относительный вызов подпрограммы), icall (Косвенный вызов подпрограммы), eicall (Расширенный косвенный вызов подпрограммы) и call k (Абсолютный вызов подпрограммы). Функционируют такие инструкции аналогично командам безусловного перехода, но с одним существенным отличием. Перед переходом в памяти программ, адрес следующей команды предварительно сохраняется в специально отведённой для этих целей области памяти (стеке). Таким образом, находясь в любой точке программы, сохраняется возможность вернутся в то место, из которого был осуществлен вызов. Это действие осуществляет команда ret (Возврат из подпрограммы). Она загружает в PC сохранённый в стеке адрес возврата, после чего программа продолжает выполняться со следующей команды после rcall k, icall, eicall, call k:
В приведенном примере подпрограмма func1 может вызываться много раз из различных мест программы. Кроме того, в теле самой подпрограммы func1 могут содержаться вызовы различных подпрограмм (вызов func2 и т.д.). Такая организация программы позволяет максимально эффективно использовать ресурсы процессора, делает код более наглядным и позволяет многократно использовать разработанные подпрограммы в дальнейших проектах.
Еще одним скрытым механизмом вызова подпрограмм являются аппаратные прерывания. При их возникновении происходит вызов подпрограммы (обработчика прерывания) по фиксированному адресу (вектору прерывания), при этом адрес возврата также запоминается в стеке. Но в отличии от вызова по командам rcall k, icall, eicall, call k ещё и автоматически сбрасывается флаг глобального разрешения прерываний I в регистре SREG, т.е. запрещаются прерывания во время прерывания. Для выхода из прерывания используется команда reti (Возврат из прерывания) которая, загружает в PC адрес возврата и восстанавливает флаг I (разрешает прерывания при выходе из прерывания):
Иногда командой reti удобно завершить и обычную подпрограмму. Так бывает, когда, например, при выходе необходимо разрешить прерывания. В этом случае она фактически заменяет собой две инструкции sei (Разрешение прерываний) и ret:
Время выполнения rcall k, icall, call k, ret, reti зависит от величины программного счётчика конкретной модели. Если его разрядность более 16 бит (≥ 128 кб FLASH памяти), то для сохранения 3-байтового адреса возврата требуется на один машинный цикл больше.
В данную группу команд включены также 4 инструкции сравнения: cp Rd,Rr (Сравнить регистры), cpс Rd,Rr (Сравнить регистры с учётом переноса), cpi Rd,K (Сравнить регистр c константой), cpse Rd,Rr (Сравнить регистры и пропустить команду если они равны). Строго говоря первые три из них не являются командами передачи управления, так как не могут оказать влияние на счётчик программ. Единственным их предназначением является сравнение числовых величин, находящихся в РОН. Как видно из описания, команда cp Rd,Rr аналогична sub Rd,Rr, вместо cpc Rd,Rr фактически выполняется sbc Rd,Rr, а вместо cpi Rd,K — cubi Rd,K. Разница заключается только лишь в том, что содержимое регистра Rd остаётся неизменным. При этом переопределяется значение флагов Z,C,S, N,V,H регистра SREG по которым и можно судить о соотношении между числовыми величинами. В частности, сравнение двухбайтовых чисел находящихся в регистровых парах R19:R18 R17:R16 можно выполнить следующим образом:
В этом примере флага C окажется установленным, когда R19:R18< R17:R16 (сброшенным, когда R19:R18>R17:R16). Что касается флага Z, то в данном случае он не может быть критерием проверки на нуль (Z=1 будет свидетельствовать только о равенстве R19=R17+C).
Стоит заметить также, что, подобно всем остальным командам, использующим непосредственную адресацию, cpi Rd,K может работать только с регистрами R16…R31.
Инструкция cpse Rd,Rr выполняется иначе. Она относится к типу Test and Skip (Проверка и пропуск). По логике работы команды такого рода выполняют проверку определённого условия и если оно истинно (в данном случае если Rd=Rr), то следующая в тексте команда пропускается. При этом все флаги программы остаются неизменными.
Помимо этого существуют ещё 4 команды Test and Skip ориентированных на проверку состояния определённого бита в регистрах. Две из них работают с РОН: sbrc Rr,b (Пропуск команды, если бит регистра сброшен), sbrs Rr,b (Пропуск команды, если бит регистра установлен). Ещё две с РВВ: sbic P,b (Пропуск команды, если бит регистра ввода-вывода сброшен), sbis P,b (Пропуск команды, если бит регистра ввода-вывода установлен). Если бит b(0…7) установлен при выполнении команд sbrs Rr,b и sbis P,b или сброшен для sbrc Rr,b, sbic P,b, то производится пропуск следующей команды. Нижеприведённый код демонстрирует программную задержку до тех пор пока не будет нажата кнопка подключённая к линии 1 порта B (пока бит 1 РВВ PINB не будет сброшен):
В отличии от команд sbrs Rr,b, sbrc Rr,b, которые работают со всеми без исключения РОН, инструкции sbis P,b, sbic P,b могут использовать только первые 32 РВВ. Если учесть, что число управляющих РВВ на много больше то, это довольно существенное ограничение. Конечно те РВВ, доступ к битам которых наиболее важен, разработчики постарались разместить именно в этой области. К ним относятся все регистры управления портами A,B,C,D,E,F, а также ряд других, отвечающих за работу EEPROM, USART, SPI т.д. Во всех остальных случаях необходимо cкопировать содержимое РВВ в один из РОН и уже дальше анализировать состояние соответствующего бита. Программное ожидание сброса бита 2 порта J должно выглядеть следующим образом:
Время выполнения инструкций Test and Skip может быть различным в зависимости от того пропускается следующая команда или нет. В первом случае необходимо 2 машинных цикла, во втором 1. Если же производится пропуск “длинной” команды состоящей из двух слов (lds Rd,k, jmp k и т.д.) на выполнение операции уйдёт 3 цикла.
Флаги программы регистра состояния также не доступны инструкциям sbis P,b, sbic P,b, но из-за важности их значения предусмотрены две команды условного перехода разработанных специально для работы с SREG: brbs s,k (Переход, если бит регистра SREG установлен), brbc s,k (Переход, если бит регистра SREG сброшен). Когда соответствующий бит s в SREG установлен для brbs s,k или сброшен для brbс s,k производится относительный переход в пределах +63…-63 слов (PC+k+1).
Ассемблер AVR поддерживает по 9 различных форм написания инструкций brbs s,k, brbc s,k для разных значений флагов программы (табл.4).
Большая Энциклопедия Нефти и Газа
Команды передачи управления , предназначенные для изменения порядка выполнения команд. Эти команды делятся на команды безусловного и условного перехода. Безусловная команда всегда передает управление в указанную в этой команде ячейку. Условная команда передает управление в какую-нибудь ячейку в зависимости от заданных условий. [1]
Команды передачи управления используются в разветвляющихся и циклических программах, а также при вызове подпрограмм и возврате из них. [2]
Команды передачи управления ( или, что то же самое, перехода или ветвления) позволяют программисту в случае необходимости принимать альтернативные решения и отступать от нормального порядка выполнения последовательных команд программы. Передача управления в ту или иную точку программы может быть произведена одним из трех способов: условно, безусловно, а также условно с изменением содержимого некоторого счетчика. [3]
Команды передачи управления играют особую роль в ЭВМ с хранимой в памяти программой. В обычном процессоре команды выполняются последовательно одна за другой в соответствии с их расположением в памяти ЭВМ. [5]
Команды передачи управления , управляющие последовательностью исполне ния команд программы. К ним относятся переходы к другой команде, вызов процедуры и возврат из нее. [6]
Команды передачи управления обеспечивают переход из одной части программы в другую. Как показано в табл. 3.9, эти команды можно подразделить на три группы: команды безусловной передачи управления, команды условной передачи управления и команды управления циклами. [7]
Команды передачи управления могут заставить микропроцессор 8088 перейти к другой части программы безусловно, при выполнении условия или при повторении блока команд — цикла. [8]
Команды передачи управления делятся на безусловные и условные переходы, осуществляемые по значению признаков. [9]
Команды передачи управления предназначены для организации перехода в программе. Существует четыре класса таких команд: безусловная передача управления, условная передача управления, управление циклами, команды прерываний. [10]
Команда передачи управления ( jump ( branch) instruction) определяет передачу управления новой последовательности команд выполняемой программы. [11]
Команды передачи управления прерывают естественный порядок выполнения команд и однозначно определяют адрес следующей команды. При выполнении команд передачи управления результат предыдущего действия сохраняется. [12]
Команды передачи управления делятся на условные и безусловные. [13]
Команды передачи управления бывают двух типов: условные и безусловные. Команды условной передачи управления определяют состояние одного из четырех признаков регистра признаков и в зависимости от этого осуществляют переход к той или иной части программы. [14]
Простейшей командой передачи управления является команда безусловного перехода JMP адрес, которая загружает адрес перехода, указанный в команде, в программный счетчик. Команды условного перехода проверяют указанное в команде условие и модифицируют программный счетчик, если условие истинно. При проверке условия производится сравнение состояния одного или нескольких флагов из флагового регистра с комбинацией, указанной в коде команды условного перехода. Модификация программного счетчика может производиться либо загрузкой в него нового значения, либо сложением его со смещением, указанным в команде. [15]
5.4. Команды передачи управления
Ранее уже отмечалось, что порядок выполнения команд может быть естественным и принудительным. При естественном порядке после выполнения очередной команды выбирается команда, расположенная в следующей по порядку ячейке памяти. Обычно адрес команды хранится в специальном регистре, называемом счетчиком адреса команд или простосчетчиком команд(СчК), содержимое которого после выполнения каждой команды увеличивается на 1. Если же память имеет побайтную адресацию, то на столько байт, сколько их содержит текущая команда. Цикл выборки/выполнения команд можно пояснить схемой, приведенной на рис. 5.10. Пусть L – длина команды в байтах, а память имеет побайтную адресацию. Порядок выполнения команд на рис. 5.10 следующий:
Выборка команды по адресу А=А1 (К1).
Дешифровка команды, в том числе определение ее длины L (L=1).
Вычисление адреса следующей команды (СчК) = (СчК) + 1 (К2).
Выполнение команды (К1).
Выборка команды по адресу А2 (К2).
Дешифровка команды, в том числе определение ее длины L (L=2).
Вычисление адреса следующей команды (СчК) = (СчК) + 2.
Выполнение команды (К2).
Далее циклы выборки/выполнения команд К3, К4, … повторяются.
Естественный порядок выполнения команд может быть нарушен командами передачи управления(командами перехода). Следует иметь в виду, что нарушение порядка выполнения команд возможно и в ряде других случаев, важнейший из которых – обработка запросов прерывания – будет рассмотрен в дальнейшем (см. п. 6).
Известны многочисленные варианты команд перехода, однако общий принцип состоит в том, что адресная часть команды перехода непосредственно или после суммирования с содержимым базового регистра загружается в СчК. В результате после выполнения такой команды может быть выполнена команда из любой ячейки памяти, определяемой адресной частью команды перехода. Для упрощения рассмотрим команды перехода без относительной адресации. Кроме того, предполагается, что память имеет побайтную адресацию.
5.4.1. Команды безусловного перехода (бп)
Общая структура команды безусловного перехода изображена на рис. 5.11. При исполнении этой команды переход осуществляется всегда независимо от каких-либо условий.

Рассмотрим два возможных варианта реализации команд БП – переход по прямому и косвенному адресам.
Переход по прямому адресу
В данном примере и далее рассматриваются команды длиной 2 байта (L = 2). При выполнении команды К2 в счетчик команд загружается адрес А4, т.е. (СчК) = А4. После этого процессор начинает выполнять команды с адреса А4. Таким образом, последовательность выполнения команд следующая: K1 K2K4 и далее по порядку.

Переход по косвенному адресу
Общая структура команды изображена на рис. 5.13. На косвенную адресацию указывает код операции команды БПК (рис. 5.13, а) или специальное поле К в структуре команды (рис. 5.13, б), определяющее тип адресации.

Управление передается команде с исполнительным адресом, хранящимся в ячейке (регистре) памяти, на адрес которой (которого) указывает адресное поле команды БПК (рис. 5.14). Преимущества косвенной регистровой адресации были описаны ранее. Следует иметь в виду, что К3 в ОП не является собственно командой по адресу А3 (рис. 5.14). По адресу А3 может не быть никакого КОП, поскольку здесь хранится только исполнительный адрес (АИ).
Как уже отмечалось, в современных ЭВМ широко используется относительная адресация при выполнении команд переходов всех типов, т.е. АИ формируется с учетом содержимого базового регистра.
Команды передачи управления
jmp адрес_перехода — безусловный переход без сохранения информации о точке возврата. Аналог goto.
Условные переходы
Команды условного перехода имеют одинаковый синтаксис:
jcc метка_перехода
Мнемокод всех команд начинается с “ j ” — от слова jump (прыжок), cc — определяет конкретное условие, анализируемое командой. Что касается операнда метка_перехода, то эта метка может находится только в пределах текущего сегмента кода, межсегментная передача управления в условных переходах не допускается.
Для того чтобы принять решение о том, куда будет передано управление командой условного перехода, предварительно должно быть сформировано условие, на основании которого и будет приниматься решение о передаче управления. Источниками такого условия могут быть:
— любая команда, изменяющая состояние арифметических флагов;
— команда сравнения cmp, сравнивающая значения двух операндов;
— состояние регистра ecx/cx.
Условные переходы по содержимому флагов
| Название флага | Номер бита в eflags/flag | Команда условного перехода | Значение флага для осуществления перехода |
| Флаг переноса cf | 1 | jc | cf = 1 |
| Флаг четности pf | 2 | jp | pf = 1 |
| Флаг нуля zf | 6 | jz | zf = 1 |
| Флаг знака sf | 7 | js | sf = 1 |
| Флаг переполнения of | 11 | jo | of = 1 |
| Флаг переноса cf | 1 | jnc | cf = 0 |
| Флаг четности pf | 2 | jnp | pf = 0 |
| Флаг нуля zf | 6 | jnz | zf = 0 |
| Флаг знака sf | 7 | jns | sf = 0 |
| Флаг переполнения of | 11 | jno | of = 0 |
jcxz метка_перехода (Jump if cx is Zero) — переход, если cx ноль;
jecxz метка_перехода (Jump Equal ecx Zero) — переход, если ecx ноль.
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры.
Model small
Stack 100h
Data
s1 db ‘числа равны$’
s2 db ‘числа не равны$’
int 21h;ввели первое число
int 21h;ввели второе число
sub al,dl;сравнили числа
mov dx, offset s1
m1: mov dx, offset s2
int 21h;выводим информационную строку
Mov ax,4 c 00 h
Int 21h
End start
Команда сравнения cmp
cmp операнд_1,операнд_2 — сравнивает два операнда и по результатам сравнения устанавливает флаги. Команда сравнения cmp имеет интересный принцип работы. Он абсолютно такой же, как и у команды вычитания sub. Единственное, чего она не делает — это запись результата вычитания на место первого операнда.
Алгоритм работы:
-выполнить вычитание (операнд1-операнд2);
-в зависимости от результата установить флаги, операнд1 и операнд2 не изменять (то есть результат не запоминать).
Условные переходы после команд сравнения
| Типы операндов | Мнемокод команды условного перехода | Критерий условного перехода | Значения флагов для осществления перехода |
| Любые | je | операнд_1 = операнд_2 | zf = 1 |
| Любые | jne | операнд_1<>операнд_2 | zf = 0 |
| Со знаком | jl/jnge | операнд_1 < операнд_2 | sf <> of |
| Со знаком | jle/jng | операнд_1 <= операнд_2 | sf <> of or zf = 1 |
| Со знаком | jg/jnle | операнд_1 > операнд_2 | sf = of and zf = 0 |
| Со знаком | jge/jnl | операнд_1 => операнд_2 | sf = of |
| Без знака | jb/jnae | операнд_1 < операнд_2 | cf = 1 |
| Без знака | jbe/jna | операнд_1 <= операнд_2 | cf = 1 or zf=1 |
| Без знака | ja/jnbe | операнд_1 > операнд_2 | cf = 0 and zf = 0 |
| Без знака | jae/jnb | операнд_1 => операнд_2 | cf = 0 |
Пример программы: определите, равны ли два числа вводимые пользователем с клавиатуры.
Model small
Stack 100h
Data
s1 db ‘числа равны$’
s2 db ‘числа не равны$’
int 21h;ввели первое число
int 21h;ввели второе число
cmp al,dl;сравнили числа
mov dx, offset s1
m1: mov dx, offset s2
int 21h;выводим информационную строку
Mov ax,4 c 00 h
Int 21h
end start
Организация циклов
loop метка_перехода (Loop) — повторить цикл
Работа команды заключается в выполнении следующих действий:
— декремента регистра ecx/cx;
— сравнения регистра ecx/cx с нулем:
— если (ecx/cx) > 0, то управление передается на метку перехода;
— если (ecx/cx) = 0, то управление передается на следующую после loop команду
mov cx, количество циклов
loope/loopz метка_перехода (Loop till cx <> 0 or Zero Flag = 0) — повторить цикл, пока cx <> 0 или zf = 0.
loopne/loopnz метка_перехода (Loop till cx <> 0 or Not Zero flag=0) — повторить цикл пока cx <> 0 или zf = 1
Недостаток команд организации цикла loop, loope/loopz и loopne/loopnz в том, что они реализуют только короткие переходы (от –128 до +127 байт).
Организация вложенных циклов
mov cх,n; в сх заносим количество итераций внешнего цикла
…
mov cx,n1; в сх заносим количество итераций внутреннего цикла
тело внутреннего цикла
Пример программы: Напишите программу подсчета у=1+2+3+…+n, n не более 10000.
s1 db ‘введите n’,10,13,’$’
mov dx, offset s1
m: shl bx,4
int 21h вводим n в регистр bx
xor dx,dx
m1: add dx,cx считаем у
Цепочечные команды
(Команды обработки строк символов)
Цепочка – это последовательность элементов, размер которых может быть байт, слово, двойное слово. Содержимое этих элементов может быть любое – символы, числа.
В системе команд микропроцессора имеется семь операций-примитивов обработки цепочек.
Каждая из них реализуется в микропроцессоре тремя командами, в свою очередь, каждая из этих команд работает с соответствующим размером элемента — байтом, словом или двойным словом.
Вместе с цепочечными командами обычно применяют префиксы повторений, которые ставятся перед командой в поле [метки]. Цепочечная команда без префикса выполняется один раз. С префиксом цепочечные команды выполняются циклично.
rep (REPeat) — команда выполняется, пока содержимое в ecx/cx не станет равным 0. При этом цепочечная команда, перед которой стоит префикс, автоматически уменьшает содержимое ecx/cx на единицу. Та же команда, но без префикса, этого не делает.
repe или repz (REPeat while Equal or Zero) — команда выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен 1. Как только одно из этих условий нарушается, управление передается следующей команде программы
repne или repnz (REPeat while Not Equal or Zero) — команда циклически выполняется до тех пор, пока содержимое ecx/cx не равно нулю или флаг zf равен нулю. При невыполнении одного из этих условий работа команды прекращается.
Формирования физического адреса операндов адрес_источника и адрес_приемника происходит следующим образом:
адрес_источника — пара ds:esi/si;
адрес_приемника — пара es:edi/di
Важный момент, касающийся всех цепочечных команд, — это направление обработки цепочки. Есть две возможности:
— от начала цепочки к ее концу, то есть в направлении возрастания адресов;
— от конца цепочки к началу, то есть в направлении убывания адресов.
Цепочечные команды сами выполняют модификацию регистров, адресующих операнды, обеспечивая тем самым автоматическое продвижение по цепочке. Количество байт, на которые эта модификация осуществляется, определяется кодом команды. А вот знак этой модификации определяется значением флага направления df (Direction Flag) в регистре eflags/flags. Состоянием флага df можно управлять с помощью двух команд, не имеющих операндов:
cld (Clear Direction Flag) — очистить флаг направления df = 0, значение индексных регистров esi/si и edi/di будет автоматически увеличиваться (операция инкремента) цепочечными командами, то есть обработка будет осуществляться в направлении возрастания адресов;
std (Set Direction Flag) — установить флаг направления df = 1, то значение индексных регистров esi/si и edi/di будет автоматически уменьшаться (операция декремента) цепочечными командами, то есть обработка будет идти в направлении убывания адресов.
Типовой набор действий для выполнения любой цепочечной команды:
— Установить значение флага df в зависимости от того, в каком направлении будут обрабатываться элементы цепочки — в направлении возрастания или убывания адресов.
— Загрузить указатели на адреса цепочек в памяти в пары регистров ds:(e)si и es: (e)di.
— Загрузить в регистр ecx/cx количество элементов, подлежащих обработке.
— Выдать цепочечную команду с префиксом повторений.
Пересылка цепочек
movs адрес_прием, адрес_источника (MOVe String)- переслать цепочку;
movsb MOVe String Byte) — переслать цепочку байт;
movsw (MOVe String Word) — переслать цепочку слов;
movsd (MOVe String Double word) — переслать цепочку двойных слов.
Команда копирует байт, слово или двойное слово из цепочки источника, в цепочку приемника. Размер пересылаемых элементов ассемблер определяет, исходя из атрибутов идентификаторов. К примеру, если эти идентификаторы были определены директивой db, то пересылаться будут байты, если идентификаторы были определены с помощью директивы dd, то пересылке подлежат двойные слова.
Для цепочечных команд с операндами типа movs адрес_приемника,адрес_источника, не существует машинного аналога. При трансляции в зависимости от типа операндов транслятор преобразует ее в одну из трех машинных команд: movsb, movsw или movsd.
Сама по себе команда movs пересылает только один элемент, исходя из его типа, и модифицирует значения регистров esi/si и edi/di. Если перед командой написать префикс rep, то одной командой можно переслать до 64 Кбайт данных. Число пересылаемых элементов должно быть загружено в счетчик — регистр cx (use16) или ecx (use32).
Пример проги. Пересылка строк командой movs
source db ‘Тестируемая строка’,’$’;строка-источник
dest db 19 DUP (‘ ‘);строка-приёмник
mov ax,@data ;загрузка сегментных регистров
mov ds,ax ;настройка регистров DS и ES на адрес сегмента данных
cld ;сброс флага DF — обработка строки от начала к концу
lea si,source ;загрузка в si смещения строки-источника
lea di,dest ;загрузка в DS смещения строки-приёмника
mov cx,20 ;для префикса rep — счетчик повторений (длина строки)
