Контроль за выполнением программы
Микроконтроллеры семейства MAXQ имеют несколько опций, позволяющий контролировать выполнение программы и обеспечивать ее ветвление. Переходы могут быть безусловные, условные, относительные или абсолютные. При вызове подпрограммы адрес возврата сохраняется в стеке и используется при выходе из подпрограммы. А для формирования циклов имеются счетчики и адресные регистры.
Получение следующего выполняемого адреса
Адрес команды, которая будет выполнена следующей, может быть в любое время получен из регистра указателя команды (IP). Это может быть особенно полезно для того, чтобы инициализировать цикл. Обратите внимание, что получаемое таким образом значение - фактический адрес текущей команды плюс 1, так что он будет адресом следующей выполненной команды только в том случае, если текущая команда не вызывает переход.
Безусловные переходы
Безусловный переход может быть относительным (IP +127/-128 слов) или абсолютным (в любую область памяти программы). Относительные переходы должны использовать непосредственно указанный 8- битный операнд. Например:
Label1: ; должен находиться в области значений +127/-128 слов от места нахождения команды JUMP
...
jump Label1
|
Абсолютные переходы могут использовать непосредственно заданный 16- разрядный операнд, 16- разрядный регистр или 8- разрядный регистр.
jump LongJump ; транслируется в команды: move PFX[0], #high(LongJump)
; jump #low(LongJump)
jump DP[0] ; абсолютный переход по адресу, содержащемся в DP[0]
|
Если для задания адреса перехода используется 8- разрядный регистр, то в качестве старшего байта адреса перехода используется префиксный регистр, а в качестве младшего байта адреса перехода - непосредственно значение указанного регистра.
Условные переходы
Условные переходы могут изменять ход выполнения программы в соответствии со значением одного из флагов состояния (C, E, Z, S). Это не относится к командам JUMP E и JUMP NE, которые выполняют безусловный абсолютный или относительный переход.
jump c, Label1 ; переход к метке Label1 если установлен флаг переноса
jump nc, LongJump ; переход к метке LongJump если не установлен флаг переноса
jump z, LC[0] ; переход по адресу, содержащемся в 16- разрядном регистре получателе
; если флаг нуля установлен
jump nz, Label1 ; переход к метке Label1 если флаг нуля не установлен (Acc<>0)
jump s, A[2] ; переход по адресу в A[2] если флаг нуля установлен
jump e, Label1 ; переход к метке Label1 если флаг эквивалентности установлен
jump ne, Label1 ; переход к метке Label1 если флаг эквивалентности не установлен
|
JUMP E и JUMP NE могут использовать только непосредственных получателей.
Вызов подпрограмм
Команда CALL работает так же, как и команда безусловного перехода, за исключением того, что адрес следующий за ней команды помещается в стек. Команда RET используется для выхода из подпрограммы при обычном вызове подпрограммы, а команда RETI - для выхода из подпрограммы обработки прерывания.
call Label1 ; если Label1 - относительное значение,
; то транслируется в команду: call #immediate
call LongCall ; транслируется в команды: move PFX[0], #high(LongCall)
; call #low(LongCall)
call LC[0] ; вызов подпрограммы, находящейся по адресу, содержащемуся в LC[0]
LongCall:
ret ; выход из подпрограммы
|
|