Поток программы продолжается последовательно, от одной инструкции к следующей инструкции, если только не выполняется инструкция передачи управления. Различные типы команд передачи управления на языке ассемблера включают в себя условные или безусловные переходы и инструкции вызова.
Инструкции по петле и прыжку
Цикл в 8051
Повторение последовательности инструкций определенное количество раз называется циклом . Инструкция DJNZ reg, метка используется для выполнения операции Loop. В этой инструкции регистр уменьшается на 1; если он не равен нулю, то 8051 переходит к целевому адресу, указанному в метке.
В регистр загружается счетчик количества повторений до начала цикла. В этой инструкции как уменьшение регистра, так и решение о переходе объединены в одну инструкцию. Регистры могут быть любыми из R0 – R7. Счетчик также может быть местом в оперативной памяти.
пример
Умножьте 25 на 10, используя технику многократного сложения.
Решение — Умножение может быть достигнуто путем добавления умножения многократно, столько раз, сколько множитель. Например,
25 * 10 = 250 (FAH)
25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 + 25 = 250
MOV A,#0 ;A = 0,clean ACC MOV R2,#10 ; the multiplier is replaced in R2 Add A,#25 ;add the multiplicand to the ACC AGAIN:DJNZ R2, AGAIN:repeat until R2 = 0 (10 times) MOV R5 , A ;save A in R5 ;R5 (FAH)
Недостаток в 8051 — Действие цикла с инструкцией DJNZ Reg ограничено только 256 итерациями. Если условный переход не выполняется, то выполняется инструкция, следующая за переходом.
Цикл внутри петли
Когда мы используем цикл внутри другого цикла, он называется вложенным циклом . Два регистра используются для хранения счетчика, когда максимальный счет ограничен 256. Поэтому мы используем этот метод, чтобы повторить действие больше, чем 256.
пример
Написать программу —
- Загрузите аккумулятор значением 55H.
- Дополните ACC 700 раз.
Решение. Поскольку 700 больше 255 (максимальная емкость любого регистра), для хранения счетчика используются два регистра. Следующий код показывает, как использовать два регистра, R2 и R3, для подсчета.
MOV A,#55H ;A = 55H NEXT: MOV R3,#10 ;R3 the outer loop counter AGAIN:MOV R2,#70 ;R2 the inner loop counter CPL A ;complement
Другие условные переходы
В следующей таблице перечислены условные переходы, используемые в 8051 —
инструкция | действие |
---|---|
JZ | Прыжок, если A = 0 |
JNZ | Прыгай, если A ≠ 0 |
DJNZ | Уменьшение и переход, если регистр ≠ 0 |
CJNE A, данные | Перейти, если данные A ≠ |
CJNE reg, #data | Перейти, если байт ≠ данных |
JC | Прыжок, если CY = 1 |
JNC | Прыгай, если CY ≠ 1 |
JB | Перейти, если бит = 1 |
JNB | Перейти если бит = 0 |
JBC | Перейти, если бит = 1 и сбросить бит |
-
JZ (переход, если A = 0) — в этой инструкции проверяется содержимое аккумулятора. Если это ноль, то 8051 переходит к целевому адресу. Инструкция JZ может использоваться только для аккумулятора, она не распространяется ни на какой другой регистр.
-
JNZ (переход, если A не равно 0) — в этой инструкции содержимое аккумулятора проверяется на ненулевое значение. Если это не ноль, то 8051 переходит к целевому адресу.
-
JNC (переход, если перенос отсутствует, прыжок, если CY = 0) — бит флага переноса в регистре флага (или PSW) используется для принятия решения о том, следует ли переходить или нет «метка JNC». Процессор смотрит на флаг переноса, чтобы увидеть, поднят ли он (CY = 1). Если оно не поднято, то процессор начинает извлекать и выполнять инструкции с адреса метки. Если CY = 1, он не будет прыгать, но выполнит следующую инструкцию ниже JNC.
-
JC (Перейти, если перенос, прыжки, если CY = 1) — Если CY = 1, он переходит на целевой адрес.
-
JB (прыгать, если бит высокий)
-
JNB (прыжок, если бит низкий)
JZ (переход, если A = 0) — в этой инструкции проверяется содержимое аккумулятора. Если это ноль, то 8051 переходит к целевому адресу. Инструкция JZ может использоваться только для аккумулятора, она не распространяется ни на какой другой регистр.
JNZ (переход, если A не равно 0) — в этой инструкции содержимое аккумулятора проверяется на ненулевое значение. Если это не ноль, то 8051 переходит к целевому адресу.
JNC (переход, если перенос отсутствует, прыжок, если CY = 0) — бит флага переноса в регистре флага (или PSW) используется для принятия решения о том, следует ли переходить или нет «метка JNC». Процессор смотрит на флаг переноса, чтобы увидеть, поднят ли он (CY = 1). Если оно не поднято, то процессор начинает извлекать и выполнять инструкции с адреса метки. Если CY = 1, он не будет прыгать, но выполнит следующую инструкцию ниже JNC.
JC (Перейти, если перенос, прыжки, если CY = 1) — Если CY = 1, он переходит на целевой адрес.
JB (прыгать, если бит высокий)
JNB (прыжок, если бит низкий)
Примечание. Следует отметить, что все условные переходы являются короткими, то есть адрес цели должен находиться в пределах от –128 до +127 байт содержимого счетчика программы.
Безусловные Инструкции Прыжка
В 8051 есть два безусловных скачка —
-
LJMP (long jump) — LJMP — это 3-байтовая инструкция, в которой первый байт представляет код операции, а второй и третий байты представляют 16-битный адрес целевого местоположения. 2-байтовый целевой адрес должен позволять переходить к любой ячейке памяти от 0000 до FFFFH.
-
SJMP (короткий переход) — это 2-байтовая инструкция, где первый байт — это код операции, а второй — относительный адрес целевого местоположения. Относительный адрес варьируется от 00H до FFH, который делится на прямой и обратный переходы; то есть в пределах от –128 до +127 байт памяти относительно адреса текущего ПК (счетчик программ). В случае прямого перехода целевой адрес может находиться в пределах 127 байт от текущего ПК. В случае обратного перехода целевой адрес может находиться в пределах –128 байтов от текущего ПК.
LJMP (long jump) — LJMP — это 3-байтовая инструкция, в которой первый байт представляет код операции, а второй и третий байты представляют 16-битный адрес целевого местоположения. 2-байтовый целевой адрес должен позволять переходить к любой ячейке памяти от 0000 до FFFFH.
SJMP (короткий переход) — это 2-байтовая инструкция, где первый байт — это код операции, а второй — относительный адрес целевого местоположения. Относительный адрес варьируется от 00H до FFH, который делится на прямой и обратный переходы; то есть в пределах от –128 до +127 байт памяти относительно адреса текущего ПК (счетчик программ). В случае прямого перехода целевой адрес может находиться в пределах 127 байт от текущего ПК. В случае обратного перехода целевой адрес может находиться в пределах –128 байтов от текущего ПК.
Расчет адреса быстрого перехода
Все условные переходы (JNC, JZ и DJNZ) являются короткими, потому что они являются 2-байтовыми инструкциями. В этих инструкциях первый байт представляет код операции, а второй байт представляет относительный адрес. Целевой адрес всегда относительно значения счетчика программы. Чтобы вычислить целевой адрес, второй байт добавляется к ПК инструкции непосредственно под переходом. Взгляните на программу, приведенную ниже —
Line PC Op-code Mnemonic Operand 1 0000 ORG 0000 2 0000 7800 MOV R0,#003 3 0002 7455 MOV A,#55H0 4 0004 6003 JZ NEXT 5 0006 08 INC R0 6 0007 04 AGAIN: INC A 7 0008 04 INC A 8 0009 2477 NEXT: ADD A, #77h 9 000B 5005 JNC OVER 10 000D E4 CLR A 11 000E F8 MOV R0, A 12 000F F9 MOV R1, A 13 0010 FA MOV R2, A 14 0011 FB MOV R3, A 15 0012 2B OVER: ADD A, R3 16 0013 50F2 JNC AGAIN 17 0015 80FE HERE: SJMP HERE 18 0017 END
Расчет целевого адреса обратного перехода
В случае скачка вперед значение смещения является положительным числом от 0 до 127 (от 00 до 7F в шестнадцатеричном формате). Однако для обратного скачка смещение имеет отрицательное значение от 0 до –128.
CALL Инструкции
CALL используется для вызова подпрограммы или метода. Подпрограммы используются для выполнения операций или задач, которые необходимо выполнять часто. Это делает программу более структурированной и экономит место в памяти. Есть две инструкции — LCALL и ACALL.
LCALL (длинный звонок)
LCALL — это 3-байтовая инструкция, где первый байт представляет код операции, а второй и третий байты используются для предоставления адреса целевой подпрограммы. LCALL может использоваться для вызова подпрограмм, которые доступны в 64-байтовом адресном пространстве 8051.
Для успешного возврата к точке после выполнения вызванной подпрограммы, CPU сохраняет адрес инструкции непосредственно под LCALL в стеке. Таким образом, когда вызывается подпрограмма, управление передается в эту подпрограмму, и процессор сохраняет ПК (программный счетчик) в стеке и начинает извлекать инструкции из нового местоположения. Инструкция RET (возврат) передает управление обратно вызывающей стороне после завершения выполнения подпрограммы. Каждая подпрограмма использует RET в качестве последней инструкции.
ACALL (абсолютный вызов)
ACALL — это 2-байтовая инструкция, в отличие от LCALL, которая составляет 3 байта. Целевой адрес подпрограммы должен быть в пределах 2K байтов, потому что только 11 битов из 2 байтов используются для адреса. Разница между ACALL и LCALL заключается в том, что целевой адрес для LCALL может находиться где угодно в пределах 64K-байтового адресного пространства 8051, в то время как целевой адрес CALL находится в пределах 2K-байтового диапазона.