6. Инструкции языка
Инструкция - это оператор, который представляет в языке ассемблера машинную команду ОМЭВМ. В процессе трансляции инструкция преобразуется в обьектный код машинной команды.
Описание машинных команд, включающее коды команд, формы записи инструкций, алгоритмы и время их выполнения, соответствуют обязательному приложению 2.4.
Обобщенная форма записи инструкции:
<инст> [<арг>] ,
где
<инст> - поле мнемокода;
<арг> - поле аргументов.
В поле мнемокода записывается мнемоническое обозначение машинной команды, определяющее операцию ОМЭВМ.
В поле аргументов записывается один, два или три аргумента.
6.3. В качестве аргумента может использоваться:
1) имя программно-доступного элемента, определяющее устройство, в котором хранится операнд операции, например:
MOV A,R1
CPL C ;
2) конструкция следующего вида:
#<выр> ,
где
<выр> - абсолютное или общее переместимое выражение языка.
Данная конструкция определяет непосредственные 8- или 16-битные данные, которые хранятся в коде команды и используются в качестве операнда операции, например:
MOV A,#1FH*2 ;(A) <= 3EH
MOV DPTR,#0FFFFH ;(DPTR) <= 0FFFFH ;
3) конструкция следующего вида:
@<рег> ,
где
<рег> - имя рабочего регистра-указателя R0, R1 или аккумулятора A,
или указателя данных DPTR, либо регистровое выражение
"A+PC", или "A+DPTR".
Данная конструкция определяет устройства,в которых хранится адрес операнда операции, например:
MOV A,@R0 ;(A) <= ((R0))
MOVC A,@A+PC ;(A) <= ((A)+(PC))
MOVC A,@A+DPTR ;(A) <=((A)+(DPTR))
MOVX @DPTR,A ;((DPTR)) <=(A) ;
4) абсолютное или общее переместимое выражение языка, определяющее адрес пространства памяти. В простейшем случае выражение представляется одним термом,таким как число, имя метки, имя обьекта типа "адрес", указатель счетчика адреса, например:
INC 10H
JMP METкA
INC ACC
DW $ ;
5) селектор бита (см. Описание директивы BIT), например:
CLR PSW.7
MOV C,20H.1 .
Разделителем поля мнемокода и поля аргументов является символ интервала ("пробел" или "горизонтальная табуляция"). Разделителем аргументов является знак "запятая".
Приложение 2.1
Регистры специальных функций ОМЭВМ-51
----------------------------------------------------------------
адрес ! имя ! назначение регистра специальной функции
----------------------------------------------------------------
! !
0E0H ! ACC ! аккумулятор
! !
0F0H ! B ! регистр B
! !
83H ! DPH ! старшие 8 разрядов регистра указателя
! ! данных DPTR
! !
82H ! DPL ! младшие 8 разрядов регистра указателя
! ! данных DPTR
! !
0A8H ! IE ! регистр управления источниками прерываний
! !
0B8H ! IP ! регистр приоритетов источников прерываний
! !
80H ! P0 ! фиксатор порта 0
! !
90H ! P1 ! фиксатор порта 1
! !
0A0H ! P2 ! фиксатор порта 2
! !
0B0H ! P3 ! фиксатор порта 3
! !
0D0H ! PSW ! регистр слова состояния программы
! !
99H ! SBUF ! буфер последовательного порта
! !
98H ! SCON ! регистр управления последовательным портом
! !
81H ! SP ! регистр указателя стека
! !
88H ! TCON ! регистр управления таймерами-счетчиками
! !
8CH ! TH0 ! старшие 8 разрядов таймера-счетчика 0
! !
8DH ! TH1 ! старшие 8 разрядов таймера-счетчика 1
! !
8AH ! TL0 ! младшие 8 разрядов таймера-счетчика 0
! !
8BH ! TL1 ! старшие 8 разрядов таймера-счетчика 1
! !
89H ! TMOD ! регистр управления режимами
! ! таймеров-счетчиков
Приложение 2.2
Триггеры специальных функций ОМЭВМ-51
----------------------------------------------------------------
адрес! имя !селектор! назначение триггера специальной функции
----------------------------------------------------------------
! ! !
0D7H ! CY ! PSW.7 ! признак переноса
! ! !
0D6H ! AC ! PSW.6 ! признак вспомогательного переноса
! ! !
0D5H ! F0 ! PSW.5 ! программно-управляемый флаг
! ! !
0D4H ! RS1 ! PSW.4 ! первый триггер выбора банка рабочих
! ! ! регистров
! ! !
0D3H ! RS0 ! PSW.3 ! нулевой триггер выбора банка рабочих
! ! ! регистров
! ! !
0D2H ! OV ! PSW.2 ! признак переполнения
! ! !
0D0H ! P ! PSW.0 ! признак четности
! ! !
8FH ! TF1 ! TCON.7 ! триггер переполнения первого
! ! ! таймера-счетчика
! ! !
8EH ! TR1 ! TCON.6 ! триггер включения первого
! ! ! таймера-счетчика
! ! !
8DH ! TF0 ! TCON.5 ! триггер переполнения нулевого
! ! ! таймера-счетчика
! ! !
8CH ! TR0 ! TCON.4 ! триггер включения нулевого
! ! ! таймера-счетчика
! ! !
8BH ! IE1 ! TCON.3 ! триггер флага первого прерывания
! ! !
8AH ! IT1 ! TCON.2 ! триггер управления первым прерыванием
! ! !
89H ! IE0 ! TCON.1 ! триггер флага нулевого прерывания
! ! !
88H ! IT0 ! TCON.0 ! триггер управления нулевым прерыванием
! ! !
9FH ! SM0 ! SCON.7 ! нулевой триггер управления режимом
! ! ! последовательного порта
! ! !
9EH ! SM1 ! SCON.6 ! первый триггер управления режимом
! ! ! последовательного порта
! ! !
9DH ! SM2 ! SCON.5 ! второй триггер управления режимом
! ! ! последовательного порта
! ! !
9CH ! REN ! SCON.4 ! триггер разрешения приема
! ! !
9BH ! TB8 ! SCON.3 ! триггер передаваемого 8-го бита данных
----------------------------------------------------------------
адрес! имя !селектор! назначение триггера специальной функции
----------------------------------------------------------------
! ! !
9AH ! RB8 ! SCON.2 ! триггер принимаемого 8-го бита данных
! ! !
99H ! II ! SCON.1 ! триггер флага прерывания передатчика
! ! !
98H ! RI ! SCON.0 ! триггер флага прерывания приемника
! ! !
0AFH ! EA ! IE.7 ! триггер запрещения всех прерываний
! ! !
0ACH ! ES ! IE.4 ! триггер разрешения прерывания от
! ! ! последовательного порта
! ! !
0ABH ! ET1 ! IE.3 ! триггер разрешения прерываний от первого
! ! ! таймера-счетчика
! ! !
0AAH ! EX1 ! IE.2 ! триггер разрешения прерываний по сигналу
! ! ! на выводе INT1
! ! !
0A9H ! ET0 ! IE.1 ! триггер разрешения прерываний от
! ! ! нулевого таймера счетчика
! ! !
0A8H ! EX0 ! IE.0 ! триггер разрешения прерываний по сигналу
! ! ! на выводе INT0
! ! !
0B7H ! RD ! P3.7 ! фиксатор сигнала чтения данных из
! ! ! внешней памяти
! ! !
0B6H ! WR ! P3.6 ! фиксатор сигнала записи данных во
! ! ! внешнюю память
! ! !
0B5H ! T1 ! P3.5 ! фиксатор внешнего сигнала для первого
! ! ! таймера-счетчика
! ! !
0B4H ! T0 ! P3.4 ! фиксатор внешнего сигнала для нулевого
! ! ! таймера-счетчика
! ! !
0B3H ! INT1! P3.3 ! фиксатор сигнала прерывания на выводе
! ! ! INT1
! ! !
0B2H ! INT0! P3.2 ! фиксатор сигнала прерывания на выводе
! ! ! INT0
! ! !
0B1H ! TXD ! P3.1 ! фиксатор предаваемого бита
! ! ! последовательного порта
! ! !
0B0H ! RXD ! P3.0 ! фиксатор принимаемого бита
! ! ! последовательного порта
! ! !
0BCH ! PS ! IP.4 ! триггер приоритета прерывания от
! ! ! последовательного порта
! ! !
0BBH ! PT1 ! IP.3 ! триггер приоритета прерывания от
! ! ! первого таймера-счетчика
! ! !
----------------------------------------------------------------
адрес! имя !селектор! назначение триггера специальной функции
----------------------------------------------------------------
0BAH ! PX1 ! IP.2 ! триггер приоритета прерывания по
! ! ! сигналу на выводе INT1
! ! !
0B9H ! PT0 ! IP.1 ! триггер приоритета прерывания от
! ! ! нулевого таймера-счетчика
! ! !
0B8H ! PX0 ! IP.0 ! триггер приоритета прерывания по
! ! ! сигналу на выводе INT0
! ! !
Приложение 2.3
Зарезервированные адреса пространства памяти программ ОМЭВМ-51
----------------------------------------------------------------
адрес ! имя ! Назначение
----------------------------------------------------------------
! !
0000H ! RESET ! адрес передачи управления при начальном
! ! запуске ОМЭВМ-51
! !
0003H ! EXTI0 ! адрес передачи управления по сигналу внешнего
! ! прерывания на выводе INT0
! !
000BH ! TIMER0! адрес передачи управления по прерыванию от
! ! нулевого таймера-счетчика
! !
0013H ! EXTI1 ! адрес передачи управления по сигналу внешнего
! ! прерывания на выводе INT1
! !
001BH ! TIMER1! адрес передачи управления по прерыванию от
! ! первого таймера-счетчика
! !
0023H ! SINT ! адрес передачи управления по прерыванию от
! ! последовательного порта ввода-вывода
! !
Приложение 2.4
Описание машинных команд ОМЭВМ - 51
1. Правила описания машинных команд
Описание каждой машинной команды состоит из словесного описания операции, выполняемой машинной командой, и представления машинной команды в виде таблицы.
Таблица, представляющая машинную команду, состоит из четырех граф: "код", "инструкция", "алгоритм" и "время".
В графе "код" приводится двоичный код машинной команды, сгруппированный в байты.
При записи кода команды используются следующие обозначения:
R - бит кода рабочего регистра-указателя R0, R1. Устанавливается
следующее соответствие между кодом Рабочего регистра-указателя
и его имени:
Код: 0 1
Имя: R0 R1
RRR - три бита кода рабочего регистра R0 - R7. Устанавливается
следующее соответствие между кодом рабочего регистра и его
именем:
Код: 000 001 010 011 100 101 110 111
Имя: R0 R1 R2 R3 R4 R5 R6 R7
DDDDDDDD - байт непосредственных данных;
BBBBBBBB
или
BSBSBSBS
или
BDBDBDBD - байт прямого адреса регистра специальной функции или ячейки
внутренней памяти данных;
IIIIIIII - байт прямого адреса триггера специальной функции или разряда
ячейки внутренней побитово адресуемой памяти данных;
DHDHDHDH
DLDLDLDL - слово непосредственных данных (первый байт- старший);
AAA
ALALALAL - прямой 11-разрядный адрес памяти программ (AAA - старшие 3 бита);
AHAHAHAH
ALALALAL - прямой 16-разрядный адрес памяти программ (первый байт -
старший);
SSSSSSSS - байт позиционно независимого смещения.
В графе "инструкция" приводится форма записи инструкции языка ассемблера, которая представляет соответствующую машинную команду. В форме записи инструкции используются следующие обозначения:
<R> - имя рабочего регистра-указателя R0, R1;
<RRR> - имя рабочего регистра R0-R7;
<D> - выражение для определения байта непосредственных данных;
<B>
или
<BS>
или
<BD> - выражение для определения байта прямого адреса регистра
специальной функции или ячейки внутренней памяти
данных;
<I> - выражение для определения байта прямого адреса триггера
специальной функции или разряда ячейки внутренней
побитово адресуемой памяти данных;
<D16> - выражение для определения слова непосредственных данных;
<A11> - выражение для определения прямого 11-битного адреса;
<A16> - выражение для определения прямого 16-битного адреса;
<S> - выражение для определения байта позиционно-независимого
смещения.
В графе "алгоритм" приводится алгоритм выполнения машинной команды ОМЭВМ-51. При записи алгоритма используются следующие обозначения:
(X) - содержимое устройства X;
((X)) - содержимое по адресу, хранящемуся в устройстве X;
X[M] - разряд M устройства X;
X[M1-MN] - группа разрядов M1-MN устройства X;
X:Y - обьединение (конкатенация) разрядов устройств X (старшая
часть) и Y;
TMP - вспомогательный регистр.
В графе "время" приведено количество циклов ОМЭВМ-51, требуемых для выполнения команды. Время выполнения одного машинного цикла определяется по следующей формуле:
T= 12 / F ,
где
T - время цикла, мкс;
F - частота генератора тактовых сигналов, мгц.
Перечень команд, устанавливающих триггеры признаков результата - C, AC, P и OV в соответствии с табл. 1.
Таблица 1
----------------------------------------------------------------
! Признаки результата
команда ----------------------------------------------------
! C ! AC ! OV ! P
----------------------------------------------------------------
ADD ! + ! + ! + ! +
MUL ! 0 ! ! + ! +
ADDC ! + ! + ! + ! +
SUBB ! + ! + ! + ! +
DIV ! 0 ! ! + ! +
DA ! + ! ! ! +
RRC ! + ! ! ! +
RLC ! + ! ! ! +
SETB C ! 1 ! ! !
CLR C ! 0 ! ! !
CPL C ! + ! ! !
ANL C,<I> ! + ! ! !
ANL C,<I> ! + ! ! !
ORL C,<I> ! + ! ! !
ORL C,/<I> ! + ! ! !
MOV C,<I> ! + ! ! !
CJNZ ! + ! ! !
! ! ! !
----------------------------------------------------------------
Примечание. Триггеры признаков результата могут быть установлены командами обращения по прямому адресу к регистру специальной функции PSW (адрес 0D0H) или к триггеру специальной функции CY (адрес 0D7H), AC (адрес 0D6H), OV (адрес 0D2H) и P (адрес 0D0H).
Арифметические команды ADD, ADDC и SUBB устанавливают триггеры признаков результата A, AC и OV следующим образом:
Если при выполнении операции сложения был перенос из 7-го разряда или при выполнении операции вычитания был заем в 7-й разряд, то триггер признака переноса C устанавливается в состояние "1", в противном случае - в состояние "0".
Если при выполнении операции сложения был перенос из 3-го разряда или при выполнении операции вычитания был заем в 3-й разряд, то триггер признака вспомогательного переноса AC устанавливается в состояние "1", в противном случае -в состояние "0".
Если при выполнении операции был перенос из 6-го разряда и не было переноса из 7-го разряда или не было переноса из 6-го разряда и был перенос из 7-го разряда, то триггер признака переполнения OV устанавливается в состояние "1", в противном случае - в состояние "0".
Триггер признака четности P устанавливается при выполнении только операций, для которых операнд-приемник размещается в аккумуляторе. Если при выполнении такой операции сумма по модулю 2 содержимого всех разрядов аккумулятора равна 1, то триггер признака четности устанавливается в состояние "1", в противном случае - в состояние "0".
Операнд-приемник операции ОМЭВМ, в инструкции, содержащей два аргумента, определяется первым аргументом, в инструкции, содержащей три аргумента, - вторым аргументом.
Примечание. Значение операнда-источника, находящегося в устройстве параллельного ввода-вывода(порт P0-P3) по прямому адресу BBBBBBBB или в разряде этого устройства по прямому адресу IIIIIIII, в процессе выполнения команды считывается с выводов ОМЭВМ; значение аналогичного операнда-приемника считывается с фиксатора соответствующего устройства. Результат в обоих случаях записывается в фиксатор устройства.
2. Команда ACALL
По команде ACALL (табл. 2) осуществляется вызов подпрограммы, расположенной в текущем банке памяти программ емкостью 2048 байт, следующим образом:
содержимое счетчика команд PC (т.е. полный адрес следуюшей команды) записывается в верхушку стека (младший байт адреса записывается первым);
содержимое указателя стека SP увеличивается на два;
в разряды 0-10 счетчика команд записывается длинный (11-битный) адрес подпрограммы, хранящийся в коде команды. Содержимое разрядов 11-15 счетчика команд не изменяется.
Таким образом, точка назначения команды ACALL должна размещаться в той же странице памяти программ , что и ее первый байт.
Таблица 2
----------------------------------------------------------------
код !инструкция !алгоритм !время
----------------------------------------------------------------
! ! !
AAA10001 !ACALL <A11> !(SP) := (SP) + 1 ! 2
ALALALAL ! !((SP)) := (PC[7-0]) !
! !(SP) := (SP) + 1 !
! !((SP)) := (PC[15-8]) !
! !(PC[10-0]) := AAA:AL...AL !
Пример выполнения команды:
;(PC)=0035H, (SP)=26H,((SP)+1)=00H,((SP)+2)=00H
;проц = 0444H
Метка: ACALL Проц
;(PC)<=0444H,(SP)<=28H,((SP)):((SP)-1)<=0035H+2
...
ORG 444H
Проц: PUSH ACC
...
RET
3. Команда ADD
По команде ADD (табл. 3):
Операнд-источник складывается с содержимым аккумулятора;
Результат записывается в аккумулятор;
Триггеры признаков результата (C), (AC), (OV) и (P) устанавливаются в соответствии с п. 1 настоящего приложения.
Таблица 3
----------------------------------------------------------------
код !инструкция !алгоритм !время
----------------------------------------------------------------
! ! !
00101RRR !ADD A,<R> !(A) := (A)+(RRR) ! 1
! !(C),(AC),(OV),(P) := 0|1 !
! ! !
0010011R !ADD A,@<R> !(A) := (A)+((R)) ! 1
! !(C),(AC),(OV),(P) := 0|1 !
! ! !
00100100 !ADD A,#<D> !(A) := (A)+D...D ! 1
DDDDDDDD ! !(C),(AC),(OV),(P) := 0|1 !
! ! !
00100101 !ADD A,<B> !(A) := (A)+(B...B) ! 1
BBBBBBBB ! !(C),(AC),(OV),(P) := 0|1 !
! ! !
----------------------------------------------------------------
Пример выполнения команды:
;(A) = 0C3H, (R0) = 0AAH
Метка: ADD A,R0
;(A) <= 0C3H + 0AAH = 6DH,
;(C) <= 1, (AC) <= 1, (OV) <= 1, (P) <= 0
4. Команда ADDC
По команде ADDC (табл. 4):
складываются операнд-источник, бит признака переноса (C) и содержимое аккумулятора;
результат записывается в аккумулятор;
триггеры признаков результата (C), (AC), (OV) и (P) устанавливаются в соответствии с п. 1. настоящего приложения.
Таблица 4
----------------------------------------------------------------
код !инструкция !алгоритм !время
----------------------------------------------------------------
! ! !
00111RRR !ADDC A,<R> !(A) := (A)+(RRR)+(C) ! 1
! !(C),(AC),(OV),(P) := 0|1 !
! ! !
0011011R !ADDC A,@<R> !(A) := (A)+((R))+(C) ! 1
! !(C),(AC),(OV),(P) := 0|1 !
! ! !
00110100 !ADDC A,#<D> !(A) := (A)+D...D+(C) ! 1
DDDDDDDD ! !(C),(AC),(OV),(P) := 0|1 !
! ! !
00110101 !ADDC A,<B> !(A) := (A)+(B...B)+(C) ! 1
BBBBBBBB ! !(C),(AC),(OV),(P) := 0|1 !
! ! !
----------------------------------------------------------------
Пример выполнения команды:
;(A) = 0C3H, (R0) = 0AAH, (C) = 0
Метка: ADDC A,R0
;(A) <= 0C3H + 0AAH + 0 = 6DH
;(C) <= 1, (AC) <= 1, (OV) <= 1, (P) <= 0
5. Команда AJMP
По команде AJMP (табл. 5) осуществляется переход в точку назначения, расположенную в текущем банке памяти программ емкостью 2048 байт, следующим образом:
в разряды 0-10 счетчика команд записывается длинный (11-битный) адрес точки назначения, представленный 7-5 разрядами первого байта AAA (старшие три разряда) и вторым (младшие восемь разрядов) байтом AL...AL кода команды. Содержимое разрядов 11-15 счетчика команд не изменяется.
Таким образом, точка назначения команды AJMP должна размещаться в той же странице памяти программ , что и ее первый байт.
Таблица 5
----------------------------------------------------------------
код !инструкция !алгоритм !время
----------------------------------------------------------------
! ! !
AAA00001 !AJMP <A11> !(PC[10-0]) := AAA:AL...AL ! 2
ALALALAL ! ! !
! ! !
----------------------------------------------------------------
Пример выполнения команды:
Цикл: MOV A,R1
;цикл = 0E80FH
...
;(PC) = 0EADCH
Метка: AJMP цикл
;(PC) <= 0E80FH
6. Команда ANL
По команде ANL (табл. 6):
операнд-источник поразрядно логически умножается на операнд-приемник;
результат записывается на место операнда-приемника.
если в качестве операнда-приемника используется содержимое аккумулятора, то триггер признака четности (P) устанавливается в соответствии с п. 1. настоящего приложения.
Таблица 6
----------------------------------------------------------------
код !инструкция !алгоритм !время
----------------------------------------------------------------
! ! !
01011RRR !ANL A,<R> !(A) := (A) и (RRR) ! 1
! !(P) := 0|1 !
! ! !
0101011R !ANL A,@<R> !(A) := (A) и ((R)) ! 1
! !(P) := 0|1 !
! ! !
01010100 !ANL A,#<D> !(A) := (A) и D...D ! 1
DDDDDDDD ! !(P) := 0|1 !
! ! !
01010101 !ANL A,<B> !(A) := (A) и (B...B) ! 1
BBBBBBBB ! !(P) := 0|1 !
! ! !
01010010 !ANL <B>,A !(B...B) := (B...B) и (A) ! 2
BBBBBBBB ! ! !
! ! !
01010011 !ANL <B>,#<D> !(B...B) := (B...B) и D...D ! 2
BBBBBBBB ! ! !
DDDDDDDD ! ! !
! ! !
10000010 !ANL C,<BIT> !(C) := (C) и (I...I) ! 2
IIIIIIII ! ! !
! ! !
10110000 !ANL C,/<BIT> !(C) := (C) и (не (I...I)) ! 2
IIIIIIII ! ! !
! ! !
----------------------------------------------------------------
Примеры выполнения команды:
;(P1) = 01010101H
Метка1: ANL P1, # 00001111H
;(P1) <= 00000101H
;установить бит переноса в единицу, если выполняется следующее
;условие: (P1.0)=1, (ACC.7)=1 и (OV)=0
Метка2: MOV C,P1.0
ANL C,ACC.7
ANL C,/OV
7. Команда C A L L
7.1. По команде C A L L (табл. 7) осуществляется вызов
подпрограммы (подобно командам ACALL и LCALL).
57
И1.00062-01 35 01 M
Т а б л и ц а 7
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
AAA10001 !CALL <выр> !см. Инструкцию ACALL ! 2
ALALALAL ! ;вел(выр)<=2047 ! !
! ! !
00010010 !CALL <выр> !см. Инструкцию LCALL ! 2
AHAHAHAH ! ;вел(выр)>=2048 ! !
ALALALAL ! ! !
! ! !
8. Команда C J N E
8.1. По команде C J N E (табл. 8) осуществляется ветвление
в программе следующим образом.
Если операнд-приемник (прий) не равен операнду-источнику
(ист), то управление передается в точку назначения(к текущему со-
держимому счетчика команд прибавляется позиционно-независимое
смещение, представленное третьим байтом кода команды S...S). В
противном случае управление передается следующей команде.
Если операнд-приемник меньше операнда-источника, то триггер
признака переноса устанавливается в состояние "1", в противном
случае - в состояние "0".
Т а б л и ц а 8
-----------------------------------------------------------------
код !инструкция !обобщенный алгоритм !время
-----------------------------------------------------------------
! ! !
10110101 !CJNE A,<B>,<S> !(PC) := (PC) + 3 ! 2
BBBBBBBB ! ;(A) - прий !если прий <> ист !
SSSSSSSS ! ;(B...B) - ист ! то (PC) := (PC)+S...S !
! !все !
10110100 !CJNE A,#<D>,<S> !если прий < ист ! 2
DDDDDDDD ! ;(A) - прий ! то (C) := 1 !
SSSSSSSS ! ;D...D - ист ! иначе (C) := 0 !
! !все !
10111RRR !CJNE <R>,#<D>,<S> ! ! 2
DDDDDDDD ! ;(RRR) - прий ! !
SSSSSSSS ! ;D...D - ист ! !
! ! !
1011011R !CJNE @<R>,#<D>,<S>! ! 2
DDDDDDDD ! ;((R)) - прий ! !
SSSSSSSS ! ;D...D - ист ! !
! ! !
Пример выполнения команды:
ORG 0100H
;(A) = 0, (P1) = 34H
;S...S = цикл-($+2) = 0125H - (0100H+2) = 23H
;(PC) = 0100H
58
И1.00062-01 35 01 M
Метка: CJNE A, P1, цикл
;(PC) <= (PC) + 2 = 0100H + 2 = 0102H
;(PC) <= (PC) + S...S = 0102H + 23H = 0125H
...
Цикл: MOV A,R1
;цикл = 0125H
9. Команда C L R
9.1. По команде C L R (табл. 9) операнд-приемник устанав-
ливается в состояние "нуль".
Если в качестве операнда-приемника используется содержимое
аккумулятора, то триггер признака четности (P) устанавливается в
состояние "1".
Т а б л и ц а 9
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11100100 !CLR A !(A) := 0 ! 1
! !(P) := 1 !
! ! !
11000011 !CLR C !(C) := 0 ! 1
! ! !
11000010 !CLR <BIT> !(I...I) := 0 ! 2
IIIIIIII ! ! !
! ! !
Примеры выполнения команды:
;(A) = 5CH
Метка1: CLR A
;(A) <= 00H
;(P1) = 01011101B
Метка2: CLR P1.2
;(P1) <= 01011001B
59
И1.00062-01 35 01 M
10. Команда C P L
10.1 по команде C P L (табл.10) операнд-приемник инверти-
руется.
Т а б л и ц а 10
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11110100 !CPL A !(A) := не (A) ! 1
! ! !
10110011 !CPL C !(C) := не (C) ! 1
! ! !
10110010 !CPL <BIT> !(I...I) := не (I...I) ! 2
IIIIIIII ! ! !
! ! !
Примеры выполнения команды:
;(A) = 10101010B
Метка1: CPL A
;(A) <= 01010101B
;(P1) = 01011101B
Метка2: CPL P1.1
;(P1) <= 01011011B
11. Команда D A
11.1. По команде D A (табл.11) результат двоичного сложения
упакованных двоично-десятичных чисел в аккумуляторе(сложение вы-
полняется командой A D D или A D D C) преобразуется в упако-
ванное двоично-десятичное число следующим образом.
Если число в младших четырех разрядах аккумулятора больше
девяти(т.е. XXXX1010B-XXXX1111B) или бит признака вспомогатель-
ного переноса AC равен единице,то к содержимому аккумулятора при-
бавляется число 6. При переносе из 7-го разряда аккумулятора
триггер признака переноса C устанавливается в состояние "1".
Если число в старших четырех разрядах аккумулятора больше
девяти (т.е. 1010XXXXB-1111XXXXB) или бит признака переноса
равен единице, то к содержимому аккумулятора прибавляется число
60H. При переносе из 7-го разряда аккумулятора триггер признака
переноса устанавливается в состояние "1".
Триггер признака четности(P) устанавливается в соотвествии с
п. 1.7 настоящего приложения.
Данная команда может быть использована для программной реа-
лизации процедуры сложения многобайтных упакобанных двоично-деся-
тичных чисел.
60
И1.00062-01 35 01 M
Т а б л и ц а 11
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11010100 !DA A !если (A[3-0]) > 9 или (AC)=1! 1
! ! то если((A)+6) > 0FFH !
! ! То (C) := 1 !
! ! Все !
! ! (A) := (A) + 6 !
! !все !
! !если (A[7-4]) > 9 или (C)=1!
! ! то если((A)+60H) > 0FFH !
! ! То (C) := 1 !
! ! Все !
! ! (A) := (A) + 60H !
! !все !
! !(P) := 0|1 !
! ! !
Пример выполнения команды:
;(A) = 56H (т.е. Двоично-десятичное число 56)
;(R3) = 67H (т.е. Двоично-десятичное число 67)
;(C) = 1
Метка: ADDC A,R3
;(A) <= 0BEH, (C) <= 0, (AC) <= 0
DA A
;(C) <= 1, (A) <= 24H
;(т. Е. Двоично-десятичное число 124)
12. Команда D E C
12.1. По команде D E C(табл.12) операнд-приемник уменьшает-
ся на единицу.
Если в качестве операнда-приемника используется содержимое
аккумулятора, то триггер признака четности (P) устанавливается в
соответствии с п. 1.7 настоящего приложения.
Из состояния 00H операнд-приемник переходит в состояние
0FFH.
Т а б л и ц а 12
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00010100 !DEC A !(A) := (A)-1 ! 1
! !(P) := 0|1 !
! ! !
00011RRR !DEC <R> !(RRR) := (RRR)-1 ! 1
! ! !
0001011R !DEC @<R> !((R)) := ((R))-1 ! 1
! ! !
00010101 !DEC <B> !(B...B) := (B...B)-1 ! 1
BBBBBBBB ! ! !
! ! !
61
И1.00062-01 35 01 M
Примеры выполнения команды:
;(R0) = 7FH, ((R0)-1) = 00H, ((R0)) = 40H
Метка: DEC @R0
DEC R0
DEC @R0
;(R0) <= 7FH - 1 = 7EH
;((R0)) <= 0FFH, ((R)+1) <= 41H
13. Команда D I V
13.1. По команде D I V (табл.13):
Содержимое аккумулятора(делимое) делится на содержимое ре-
гистра B (делитель);
Целая часть результата(частное) записывается в аккумулятор,
остаток от деления - в регистр B;
Триггер признака переноса (C) устанавливается в состояние
"0"; триггер признака переполнения(OV) устанавливается в состоя-
ние "1", если делитель в регистре B равно нулю, в противном слу-
чае - в состояние "0"; триггер признака четности (P) устанавли-
вается в соответствии с п. 1.7 настоящего приложения.
Операнды команды рассматриваются, как порядковые числа.
Если делитель равен нулю, то результат выполнения команды
неопределен.
Т а б л и ц а 13
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
10000100 !DIV AB !если (B) = 0 ! 4
! ! то (OV) := 1 !
! ! иначе (OV) := 0 !
! !все !
! !(TMP) := (A)/(B) !
! !(B) := (A) мод (B) !
! !(A) := (TMP) !
! !(C) := 0 !
! !(P) := 0|1 !
! ! !
Примеры выполнения команды:
;(A) = 0FBH, (B) = 12H
Метка: DIV AB
;(A)<=0DH и (B)<=11H, так как 0FBH=0DH*12H+11H
;(C) <= 0, (OV) <= 0, (P) <= 0
14. Команда D J N Z
14.1. По команде D J N Z (табл.14) осуществляется ветвление
в программе следующим образом.
Операнд-приемник уменьшается на единицу. Затем,если операнд-
приемник не равен нулю, то управление передается в точку назначе-
ния(к текущему содержимому счетчика команд прибавляется позицион-
62
И1.00062-01 35 01 M
но-независимое смещение, представленное третьим байтом кода ко-
манды S...S). В противном случае управление передается следующей
команде.
при уменьшении операнд-приемник из состояния 00H переходит в
состояние 0FFH.
Т а б л и ц а 14
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11011RRR !DJNZ <R>,<S> !(PC) := (PC) + 2 ! 2
SSSSSSSS ! !(RRR) := (RRR) - 1 !
! !если (RRR) <> 0 !
! ! то (PC) := (PC)+S...S !
! !все !
! ! !
11010101 !DJNZ <B>,<S> !(PC) := (PC) + 3 ! 2
BBBBBBBB ! !(B...B) := (B...B) - 1 !
SSSSSSSS ! !если (B...B) <> 0 !
! ! то (PC) := (PC)+S...S !
! !все !
! ! !
Пример выполнения команды:
ORG 0100H
;(P1) = 34H
;S...S = цикл - ($+2) = 0125H - (0100H+2)=23H
;(PC) = 0100H
Метка: DJNZ P1, цикл
;(P1) <= 33H
;(PC) <= (PC) + 2 = 0100H + 2 = 0102H
;(PC) <= (PC) + S...S = 0102H + 23H = 0125H
...
Цикл: MOV A,R1
;цикл = 0125H
15. Команда I N C
15.1. По команде I N C (табл.15) операнд-приемник увеличи-
вается на единицу.
Если в качестве операнда-приемника используется содержимое
аккумулятора, то триггер признака четности (P) устанавливается в
соответствии с п. 1.7 настоящего приложения.
Из состояния 0FFH операнд-приемник переходит в состояние
00H.
63
И1.00062-01 35 01 M
Т а б л и ц а 15
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00000100 !INC A !(A) := (A)+1 ! 1
! !(P) := 0|1 !
! ! !
00001RRR !INC <R> !(RRR) := (RRR)+1 ! 1
! ! !
0000011R !INC @<R> !((R)) := ((R))+1 ! 1
! ! !
00000101 !INC <B> !(B...B) := (B...B)+1 ! 1
BBBBBBBB ! ! !
! ! !
10100011 !INC DPTR !(DPTR) := (DPTR)+1 ! 2
! ! !
Примеры выполнения команды:
;(R0) = 7EH, ((R0)) = 0FFH, ((R0)+1) = 40H
Метка1: INC @R0
INC R0
INC @R0
;(R0) <= 7EH + 1 = 7FH
;((R0)) <= 00H, ((R)+1) <= 41H
;(DPH) = 12H, (DPL) = 0FEH
Метка2: INC DPTR
INC DPTR
INC DPTR
;(DPH) <= 13H, (DPL) <= 01H
16. Команда J B
16.1. По команде J B (табл.16) осуществляется ветвление
в программе следующим образом.
Если прямо адресуемый бит ячейки внутренней памяти данных
или регистра специальной функции равен единице, то управление пе-
редается в точку назначения (к текущему содержимому счетчика ко-
манд прибавляется позиционно-независимое смещение, представленное
третьим байтом кода команды S...S). В противном случае управление
передается следующей команде.
Прямой адрес анализируемого бита данных представляется вто-
рым байтом кода команды I...I.
Т а б л и ц а 16
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00100000 !JB <S> !(PC) := (PC) + 3 ! 2
IIIIIIII ! !если (I...I) = 1 !
SSSSSSSS ! ! то (PC) := (PC) + S...S !
! !все !
! ! !
64
И1.00062-01 35 01 M
Пример выполнения команды:
Цикл: MOV A,R1
;цикл = 0125H
...
ORG 0150H
;(P1) = 00000100B
;S...S = цикл - ($+2) = 0125H - (0150H+2)=-2DH
; (т.е. 0D3H)
Метка: JB P1.2, цикл
;(PC) <= (PC) + 2 = 0150H + 2 = 0152H
;(PC) <= (PC) + S...S = 0152H + (-2DH) = 0125H
17. Команда J B C
17.1. По команде J B C (табл.17) осуществляется ветвление в
программе следующим образом.
Если прямо адресуемый бит ячейки внутренней памяти данных
или регистра специальной функции равен единице, то этот бит ус-
танавливается в состояние "нуль", а управление передается в точку
назначения (к текущему содержимому счетчика команд прибавляется
позиционно-независимое смещение, представленное третьм байтом ко-
да команды S...S). В противном случае управление передается сле-
дующей команде.
Прямой адрес анализируемого бита данных представляется вто-
рым байтом кода команды I...I.
Т а б л и ц а 17
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00010000 !JBC <BIT>,<S> !(PC) := (PC) + 3 ! 2
IIIIIIII ! !если (I...I) = 1, !
SSSSSSSS ! ! то (I...I) := 0 !
! ! (PC) := (PC) + S...S !
! !все !
! ! !
Пример выполнения команды:
Цикл: MOV A,R1
;цикл = 0125H
...
ORG 0150H
;(P1) = 00000100B
;S...S = цикл - ($+2) = 0125H - (0150H+2)=-2DH
; (т.е. 0D3H)
Метка: JBC P1.2, цикл
;(P1) <= 00000000B
;(PC) <= (PC) + 2 = 0150H + 2 = 0152H
;(PC) <= (PC) + S...S = 0152H + (-2DH) = 0125H
65
И1.00062-01 35 01 M
18. Команда J C
18.1. По команде J C (табл.18) осуществляется ветвление в
программе следующим образом.
Если бит признака переноса(C) равен единице, то управление
передается в точку назначения (к текущему содержимому счетчика
команд прибавляется позиционно-независимое смещение, представлен-
ное вторым байтом кода команды S...S). В противном случае управ-
ление передается следующей команде.
Т а б л и ц а 18
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
01000000 !JC <S> !(PC) := (PC) + 2 ! 2
SSSSSSSS ! !если (C) = 1 !
! ! то (PC) := (PC) + S...S !
! !все !
! ! !
Пример выполнения команды:
Цикл: MOV A,R1
;цикл = 0125H
...
ORG 0150H
;(C) = 1
;S...S=цикл-($+2)=0125H-(0150H+2)=-2DH
Метка: JC цикл ;(т.е. 0D3H)
;(PC) <= (PC) + 2 = 0150H + 2 = 0152H
;(PC) <= (PC) + S...S = 0152H + (-2DH) = 0125H
19. Команда J M P
19.1. По команде J M P (табл.19) осуществляется безусловный
прямой (подобно командам SJMP, AJMP и LJMP) или косвенный переход
в точку назначения.
В случае косвенного перехода содержимое счетчика команд ус-
танавливается равным сумме содержимого аккумулятора и содержимого
регистра указателя данных DPTR. Сумма вычисляется по модулю
2**16. Содержимое аккумулятора интерпретируется, как целое число
без знака в пределах от нуля до 255.
Т а б л и ц а 19
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
10000000 !JMP <выр> !см. Инструкцию SJMP ! 2
SSSSSSSS ! ;вел(выр)<=255 ! !
! ! !
! ! !
66
И1.00062-01 35 01 M
Продолжение т а б л. 19
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
AAA00001 !JMP <выр> !см. Инструкцию AJMP ! 2
ALALALAL ! ;вел(выр)>=256 и ! !
! ;вел(выр)<=2047 ! !
! ! !
00000010 !JMP <выр> !см. Инструкцию LJMP ! 2
AHAHAHAH ! ;вел(выр)>=2048 ! !
ALALALAL ! ! !
! ! !
01110011 !JMP @A+DPTR !(PC) := (A) + (DPTR) ! 2
! ! !
Пример выполнения команды:
MOV DPTR,#JMP_TBL
;(A) = 04H, (DPTR) = 1000H
JMP @A+DPTR
;(PC) <= 1004H
JMP_TBL:
JMP LABEL0 ;$=1000H
JMP LABEL1 ;$=1002H
JMP LABEL2 ;$=1004H
;переход после выполнения команды JMP @A+DPTR
JMP LABEL3 ;$=1006H
67
И1.00062-01 35 01 M
20. Команда J N B
20.1. По команде J N B (табл.20) осуществляется ветвление
в программе следующим образом.
Если прямо адресуемый бит ячейки внутренней памяти данных
или регистра специальной функции равен нулю, то управление пере-
дается в точку назначения (к текущему содержимому счетчика ко-
манд прибавляется позиционно-независимое смещение, представленное
третьм байтом кода команды S...S). В противном случае управление
передается следующей команде.
Прямой адрес анализируемого бита данных представляется вто-
рым байтом кода команды I...I.
Т а б л и ц а 20
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00110000 !JNB <S> !(PC) := (PC) + 3 ! 2
IIIIIIII ! !если (I...I) = 0 !
SSSSSSSS ! ! то (PC) := (PC) + S...S !
! !все !
! ! !
Пример выполнения команды:
ORG 0100H
;(ACC) = 00001000B
;S...S = цикл - ($+2) = 0125H - (0100H+2)=23H
;(PC) = 0100H
Метка: JNB ACC.3, цикл
;(PC) <= (PC) + 2 = 0100H + 2 = 0102H
;(PC) <= (PC) + S...S = 0102H + 23H = 0125H
...
Цикл: MOV A,R1
;цикл = 0125H
21. Команда J N C
21.1. По команде J N C (табл.21) осуществляется ветвление
в программе следующим образом.
Если бит признака переноса(C) равен нулю, то управление пе-
редается в точку назначения (к текущему содержимому счетчика ко-
манд прибавляется позиционно-независимое смещение, представленное
вторым байтом кода команды S...S). В противном случае управление
передается следующей команде.
Т а б л и ц а 21
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
01010000 !JNC <S> !(PC) := (PC) + 2 ! 2
SSSSSSSS ! !если (C) = 0 !
! ! то (PC) := (PC) + S...S !
! !все !
! ! !
68
И1.00062-01 35 01 M
Пример выполнения команды:
ORG 0100H
;(C) = 0
;S...S=цикл - ($+2) = 0125H - (0100H+2)= 23H
;(PC) = 0100H
Метка: JNC цикл
;(PC) <= (PC) + 2 = 0100H + 2 = 0102H
;(PC) <= (PC) + S...S = 0102H + 23H = 0125H
...
Цикл: MOV A,R1
;цикл = 0125H
22. Команда J N Z
22.1. По команде J N Z (табл.22) осуществляется ветвление
в программе следующим образом.
Если содержимое аккумулятора не равно нулю, то управление
передается в точку назначения (к текущему содержимому счетчика
команд прибавляется позиционно-независимое смещение, представлен-
ное вторым байтом кода команды S...S). В противном случае управ-
ление передается следующей команде.
Т а б л и ц а 22
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
01110000 !JNZ <S> !(PC) := (PC) + 2 ! 2
SSSSSSSS ! !если (A) <> 0 !
! ! то (PC) := (PC) + S...S !
! !все !
! ! !
Пример выполнения команды:
ORG 0100H
;(A) <> 0
;S...S=цикл - ($+2) = 0125H - (0100H+2) = 23H
;(PC) = 0100H
Метка: JNZ цикл
;(PC) <= (PC) + 2 = 0100H + 2 = 0102H
;(PC) <= (PC) + S...S = 0102H + 23H = 0125H
...
Цикл: MOV A,R1
;цикл = 0125H
23. Команда J Z
23.1. По команде J Z (табл.23) осуществляется ветвление в
программе следующим образом.
69
И1.00062-01 35 01 M
Если содержимое аккумулятора равно нулю, то управление пере-
дается в точку назначения (к текущему содержимому счетчика команд
прибавляется позиционно-независимое смещение, представленное вто-
рым байтом кода команды S...S). В противном случае управление пе-
редается следующей команде.
Т а б л и ц а 23
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
01100000 !JZ <S> !(PC) := (PC) + 2 ! 2
SSSSSSSS ! !если (A) = 0 !
! ! то (PC) := (PC) + S...S !
! !все !
! ! !
Пример выполнения команды:
Цикл: MOV A,R1
;цикл = 0125H
...
ORG 0150H
;(A) = 0
;S...S=цикл-($+2)=0125H-(0150H+2)=-2DH
Метка: JZ цикл (т.е. 0D3H)
;(PC) <= (PC) + 2 = 0150H + 2 = 0152H
;(PC) <= (PC) + S...S = 0152H + (-2DH) = 0125H
24. Команда L C A L L
24.1. По команде L C A L L (табл.24) осуществляется вызов
подпрограммы, расположенной в любой точке памят и программ, сле-
дующим образом:
Содержимое счетчика команд PC (т.е. Полный адрес следуюшей
команды) записывается в верхушку стека (младший байт адреса запи-
сывается первым);
Содержимое указателя стека SP увеличивается на два;
В счетчик команд записывается полный (16-битный) адрес под-
программы, представленный вторым (старшим) AH...AH и третьим
(младшим) AL...AL байтами кода команды.
Т а б л и ц а 24
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00010010 !LCALL <A16> !(SP) := (SP) + 1 ! 2
AHAHAHAH ! !((SP)) := (PC[7-0]) !
ALALALAL ! !(SP) := (SP) + 1 !
! !((SP)) := (PC[15-8]) !
! !(PC) := AH...AH:AL...AL !
! ! !
70
И1.00062-01 35 01 M
Пример выполнения команды:
;(PC)=0035H,(SP)=26H, ((SP)+1)=00H,((SP)+2)=00H
;проц = 8000H
Метка: LCALL проц
;(PC)<=8000H,(SP)<=28H,((SP)):((SP)-1)<=0035H+2
...
ORG 8000H
Проц: PUSH ACC
...
RET
25. Команда L J M P
25.1. По команде L J M P (табл.25) осуществляется безус-
ловный переход в точку назначения, расположенную в любом месте
памяти программ, следующим образом:
В счетчик команд записывается полный (16-битный) адрес точ-
ки назначения, представленный вторым (старшим) и третьим (млад-
шим) байтами кода команды.
Т а б л и ц а 25
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00000010 !LJMP <A16> !(PC) := AH...AH:AL...AL ! 2
AHAHAHAH ! ! !
ALALALAL ! ! !
! ! !
Пример выполнения команды:
Цикл: MOV A,R1
;цикл = 0080FH
...
;(PC) = 0EADCH
Метка: LJMP цикл
;(PC) <= 0080FH
26. Команда M O V
26.1. По команде M O V (табл.26) операнд-источник пересы-
лается на место операнда-приемника.
Если в качестве операнда-приемника используется содержимое
аккумулятора, то триггер признака четности (P) устанавливается в
соответствии с п. 1.7 настоящего приложения.
71
И1.00062-01 35 01 M
Т а б л и ц а 26
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
11101RRR !MOV A,<R> !(A) := (RRR) ! 1
! !(P) := 0|1 !
! ! !
1110011R !MOV A,@<R> !(A) := ((R)) ! 1
! !(P) := 0|1 !
! ! !
01110100 !MOV A,#<D> !(A) := D...D ! 1
DDDDDDDD ! !(P) := 0|1 !
! ! !
11100101 !MOV A,<B> !(A) := (B...B) ! 1
BBBBBBBB ! !(P) := 0|1 !
! ! !
11111RRR !MOV <R>,A !(RRR) := (A) ! 1
! ! !
01111RRR !MOV <R>,#<D> !(RRR) := D...D ! 1
DDDDDDDD ! ! !
! ! !
10101RRR !MOV <R>,<B> !((RRR) := (B...B) ! 1
BBBBBBBB ! ! !
! ! !
1111011R !MOV @<R>,A !((R)) := (A) ! 1
! ! !
0111011R !MOV @<R>,#<D> !((R)) := D...D ! 1
DDDDDDDD ! ! !
! ! !
1010011R !MOV @<R>,<B> !((R)) := (B...B) ! 1
BBBBBBBB ! ! !
! ! !
11110101 !MOV <B>,A !(B...B) := (A) ! 2
BBBBBBBB ! ! !
! ! !
10001REG !MOV <B>,<REG> !(B...B) := (REG) ! 1
BBBBBBBB ! ! !
! ! !
1000011R !MOV <B>,@<R> !(B...B) := ((R)) ! 1
BBBBBBBB ! ! !
! ! !
01110101 !MOV <B>,#<DATA> !(B...B) := DATA ! 2
BBBBBBBB ! ! !
DDDDDDDD ! ! !
! ! !
10000101 !MOV <BD>,<BS> !(BD...BD) := (BS...BS) ! 2
BSBSBSBS ! ! !
BDBDBDBD ! ! !
! ! !
10010000 !MOV DPTR,#<D16> !(DPTR) := DH...DH:DL...DL ! 2
DHDHDHDH ! ! !
DLDLDLDL ! ! !
! ! !
10100010 !MOV C,<BIT> !(C) := (I...I) ! 1
IIIIIIII ! ! !
! ! !
10010010 !MOV <BIT>,C !(I...I) := (C) ! 2
IIIIIIII ! ! !
72
И1.00062-01 35 01 M
Примеры выполнения команды:
Метка1: MOV R0,#30H
;(R0) <= 30H
;((R0)) = 40H
MOV A,@R0
;(A) <= 40H
MOV R1,A
;(R1) <= 40H
;((R1)) = 10H
MOV B,@R1
;(B) <= 10H
Метка2: MOV DPTR,#1234H
;(DPH) <= 12H, (DPL) <= 34H
;(C) = 1, (P3) = 00000000B
Метка3: MOV P3.2, C
;(P3) <= 00000100B
27. Команда M O V C
27.1. По команде M O V C (табл.27) операнд-источник (байт
кода команды или 8-битная константа) из памяти программ пересы-
лается в аккумулятор.
Имеется два способа формирования адреса операнда-источника:
1) как сумма содержимого аккумулятора и регистра указателя
данных DPTR;
2) как сумма содержимого аккумулятора и регистра счетчика
команд PC.
Примечания.
1. После выборки текущей команды счетчик команд увеличивает-
ся на число, равное количеству байт, занимаемых этой командой
(для команды MOVC - на единицу).
2. Старший байт адреса передается через порт #2, младщий -
через порт #0.
Триггер признака четности (P) устанавливается в соответствии
с п. 1.7 настоящего приложения.
Т а б л и ц а 27
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
10010011 !MOVC A,@A+DPTR !(A) := ((A)+(DPTR)) ! 2
! !(P) := 0|1 !
! ! !
10000011 !MOVC A,@A+PC !(A) := ((A)+(PC)) ! 2
! !(P) := 0|1 !
! ! !
73
И1.00062-01 35 01 M
Примеры выполнения команды:
;(A) = 1
Субр: INC A
;(A) <= 2
MOVC A,@A+PC
;(A) <= (2 + $+1) = 77H
RET
DB 66H
DB 77H
DB 88H
DB 99H
;$ - адрес команды MOVC
28. Команда M O V X
28.1. Имеется два типа команды MOVX (табл.28).
По команде первого типа операнд-источник из внешней памяти
данных пересылается в аккумулятор.
По команде второго типа содержимое аккумулятора пересылает-
ся во внешнюю память данных.
В качестве адреса ячейки памяти данных может использоваться:
1) содержимое рабочего регистра с кодом R (т.е. R0 и R1). В
этом случае адрес и данные мультиплексно передаются через порт
#0. Размер адресуемой области данных - 256 байт. С целью увеличе-
ния размера адресуемой области данных до 64 кбайт, рекомендуется
использовать порт #2 для предварительной передачи старшего байта
адреса;
2) содержимое регистра указателя данных DPTR. Младший байт
адреса мультиплексно передается через порт #0, старший байт - че-
рез порт #2. В фиксаторе порта #2 (т.е. P2) восстанавливается его
предварительно сохраненное значение. В буфер порта #2 записывают-
ся пересылаемые данные. Размер адресуемой области данных - 64
кбайт.
Если в качестве операнда-приемника используется содержимое
аккумулятора, то триггер признака четности (P) устанавливается в
соответствии с п. 1.7 настоящего приложения.
Т а б л и ц а 28
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
1110001R !MOVX A,@<R> !(A) := ((R)) ! 2
! !(P) := 0|1 !
! ! !
11100000 !MOVX A,@DPTR !(A) := ((DPTR)) ! 2
! !(P) := 0|1 !
! ! !
1111001R !MOVX @<R>,A !((R)) := (A) ! 2
! ! !
11110000 !MOVX @DPTR,A !((DPTR)) := (A) ! 2
! ! !
74
И1.00062-01 35 01 M
Примеры выполнения команды:
;(R0) = 12H, (R1) = 34H, ((R1)) = 56H
Метка: MOVX A,@R1
;(A) <= 56H
MOVX @R0,A
;((R0)) <= 56H
29. Команда M U L
29.1. По команде M U L (табл.29):
Содержимое аккумулятора умножается на содержимое регистра B;
Результат записывается в регистровую пару AB (младший байт -
в регистр A, старший - в регистр B).
Триггер признака переноса (C) устанавливается в состояние
"0"; триггер признака переполнения (OV) - в состояние "0", если
старший байт результата равен нулю, или в состояние "1", в про-
тивном случае; триггер признака четности (P) устанавливается в
соответствии с п. 1.7 настоящего приложения.
Операнды команы рассматриваются, как порядковые числа.
Т а б л и ц а 29
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
10100100 !MUL AB !(A):(B) := (A)*(B) ! 4
! !(C) := 0 !
! !если (AB) > 255 !
! ! то (OV) := 1 !
! ! иначе (OV) := 0 !
! !все !
! !(P) := 0|1 !
! ! !
Примеры выполнения команды:
;(A) = 50H, (B) = 0A0H
Метка: MUL AB
;(B):(A) <= 3200H
;(C) <= 0, (OV) <= 0, (P) <= 1
75
И1.00062-01 35 01 M
30. Команда N O P
30.1. По команде N O P (табл.30) выполняется холостая опе-
рация ОМЭВМ-51 (содержимое счетчика команд увеличивается на еди-
ницу).
Т а б л и ц а 30
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00000000 !NOP !(PC) := (PC) + 1 ! 1
! ! !
Пример выполнения команды:
CLR P2.7
;(PC) = 0100H
NOP
NOP
NOP
NOP
;(PC) <= 0104H
SETB P2.7
31. Команда O R L
31.1. По команде O R L (табл.31):
Операнд-источник поразрядно логически складывается с операн-
дом-приемником;
Результат записывается на место операнда-приемника.
Если в качестве операнда-приемника используется содержимое
аккумулятора, то триггер признака четности (P) устанавливается в
соответствии с п. 1.7 настоящего приложения.
Т а б л и ц а 31
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
01001RRR !ORL A,<R> !(A) := (A) или (RRR) ! 1
! !(P) := 0|1 !
! ! !
0100011R !ORL A,@<R> !(A) := (A) или ((R)) ! 1
! !(P) := 0|1 !
! ! !
01000100 !ORL A,#<D> !(A) := (A) или D...D ! 1
DDDDDDDD ! !(P) := 0|1 !
! ! !
01000101 !ORL A,<B> !(A) := (A) или (B...B) ! 1
BBBBBBBB ! !(P) := 0|1 !
! ! !
01000010 !ORL <B>,A !(B...B) := (B...B) или (A) ! 2
BBBBBBBB ! ! !
76
И1.00062-01 35 01 M
Продолжение т а б л. 31
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
01000011 !ORL <B>,#<D> !(B...B):=(B...B) или D...D ! 2
BBBBBBBB ! ! !
DDDDDDDD ! ! !
! ! !
01110010 !ORL C,<BIT> !(C) := (C) или (I...I) ! 2
IIIIIIII ! ! !
! ! !
01010000 !ORL C,/<BIT> !(C) := (C) или (не (I...I)) ! 2
IIIIIIII ! ! !
! ! !
Примеры выполнения команды:
;(P1) = 01010101H
Метка1: ORL P1, # 00001111H
;(P1) <= 01011111H
; установить бит переноса в единицу, если
; выполняется следующее условие: (P1.0) = 1
;или (ACC.7)=1 или (OV)=0
Метка2: MOV C,P1.0
ORL C,ACC.7
ORL C,/OV
32. Команда P O P
32.1. По команде P O P (табл.32):
Содержимое стека по адресу, находящемуся в регистре указате-
ля стека SP, пересылается в ячейку внутренней памяти данных или
в регистр специальной функции, прямо адресесуемого вторым байтом
кода команды B...B;
Содержимое регистра указателя стека SP уменьшается на едини-
цу.
Т а б л и ц а 32
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11010000 !POP <B> !(B...B) := ((SP)) ! 2
BBBBBBBB ! !(SP) := (SP) - 1 !
! ! !
Пример выполнения команды:
;(SP)=99H,((SP))=12H,((SP)-1)=34H,((SP)-2)=04H
Метка: POP DPL
POP DPH
;(DPTR) <= 1234H, (SP) <= 97H
POP SP
;(SP) <= 04H
77
И1.00062-01 35 01 M
33. Команда P U S H
33.1. По команде P U S H (табл.33):
Содержимое регистра указателя стека SP увеличивается на еди-
ницу;
Содержимое ячейки внутренней памяти данных или содержимое
регистра специальной функции, прямо адресесуемой вторым байтом
кода команды B...B, записывается в стек по адресу, находящемуся в
регистре указателя стека SP.
Т а б л и ц а 33
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11000000 !PUSH <B> !(SP) := (SP) + 1 ! 2
BBBBBBBB ! !((SP)) := (B...B) !
! ! !
Пример выполнения команды:
;(SP) = 09H, (DPTR) = 1234H
Метка: PUSH DPL
PUSH DPH
;(SP) <= 0BH, ((SP)) <= 12H, ((SP)-1) <= 34H
34. Команда R E T
34.1. По команде R E T (табл.34) осуществляется возврат из
подпрограммы, котороя была вызвана командой CALL, ACALL или
LCALL, следующим образом:
Содержимое верхушкы стека(т.е. Полный адрес возврата из под-
программы) пересылается в счетчик команд PC;
Содержимое указателя стека SP уменьшается на два.
Т а б л и ц а 34
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00100010 !RET !(PC[15-8]) := ((SP)) ! 2
! !(SP) := (SP) - 1 !
! !(PC[7-0]) := ((SP)) !
! !(SP) := (SP) - 1 !
! ! !
Пример выполнения команды:
LCALL проц
...
ORG 8000H
Проц: PUSH ACC
...
;(PC) = 8051H,(SP) = 28H,((SP)):((SP)-1)=0037H
Метка: RET
;(PC) <= 0037H, (SP) <= 26H
78
И1.00062-01 35 01 M
35. Команда R E T I
35.1. По команде R E T I (табл.35) осуществляется возврат
из подпрограммы обслуживания прерывания следующим образом:
Содержимое верхушкы стека(т.е. Полный адрес возврата в точ-
ку прерывания) пересылается в счетчик команд PC. Точкой прерыва-
ния является команда, следующая за командой, во время выполнения
которой поступил запрос на прерывание;
Содержимое указателя стека SP уменьшается на два;
Разрешает прерывания равного или меньшего уровня.
Примечание. Если во время выполнения команды RETI пришел
запрос на прерывание равного или меньшего уровня, то его обработ-
ка начинается только после выполнения следующей команды.
Т а б л и ц а 35
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00110010 !RETI !(PC[15-8]) := ((SP)) ! 2
! !(SP) := (SP) - 1 !
! !(PC[7-0]) := ((SP)) !
! !(SP) := (SP) - 1 !
! ! !
Пример выполнения команды:
ORG 0003H
JMP INT_0
...
ORG 8000H
INT_0: PUSH ACC
...
;(PC) = 8051H,(SP) = 28H,((SP)):((SP)-1)=0037H
Метка: RETI
;(PC) <= 0037H, (SP) <= 26H
36. Команда R L
36.1. По команде R L (табл.36) содержимое аккумулятора
циклически сдвигается влево на один двоичный разряд.
Триггер признака четности (P) устанавливается в соответстви
с п. 1.7 настоящего приложения.
Т а б л и ц а 36
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00100011 !RL A !для N от 6 до 0 ! 1
! ! нц !
! ! (A[N+1]) := (A[N]) !
! ! кц !
! !(A[0]) := (A[7]) !
! !(P) := 0|1 !
! ! !
79
И1.00062-01 35 01 M
Примеры выполнения команды:
;(A) = 11110000B
Метка: RL A
;(A) <= 11100001B
37. Команда R L C
37.1. По команде R L C (табл.37) содержимое аккумулятора и
бит признака переноса циклически сдвигаются влево на один двоич-
ный разряд.
Триггер признака четности (P) устанавливается в соответствии
с п. 1.7 настоящего приложения.
Т а б л и ц а 37
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00110011 !RLC A !(TMP) := (C) ! 1
! !(C) := (A[7]) !
! !для N от 6 до 0 !
! ! нц !
! ! (A[N+1]) := (A[N]) !
! ! кц !
! !(A[0]) := (TMP) !
! !(P) := 0|1 !
! ! !
Примеры выполнения команды:
;(C) = 0, (A) = 11111111B
Метка: RLC A
;(C) <= 1, (A) <= 11111110B
38. Команда R R
38.1. По команде R R (табл.38) содержимое аккумулятора
циклически сдвигается вправо на один двоичный разряд.
Триггер признака четности (P) устанавливается в соответствии
с п. 1.7 настоящего приложения.
Т а б л и ц а 38
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00000011 !RR A !для N от 0 до 6 ! 1
! ! нц !
! ! (A[N]) := (A[N+1]) !
! ! кц !
! !(A[7]) := (A[0]) !
! !(P) := 0|1 !
! ! !
80
И1.00062-01 35 01 M
Примеры выполнения команды:
;(A) = 11110000B
Метка: RR A
;(A) <= 01111000B
39. Команда R R C
39.1. По команде R R C (табл.39) содержимое аккумулятора и
бит признака переноса циклически сдвигаются вправо на один двоич-
ный разряд.
Триггер признака четности(P) устанавливается в соответствии
с п. 1.7 настоящего приложения.
Т а б л и ц а 39
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
00010011 !RRC A !(TMP) := (C) ! 1
! !(C) := (A[0]) !
! !для N от 0 до 6 !
! ! нц !
! ! (A[N]) := (A[N+1]) !
! ! кц !
! !(A[7]) := (TMP) !
! !(P) := 0|1 !
! ! !
Примеры выполнения команды:
;(A) = 11111111B, (C) = 0,
Метка: RRC A
;(A) <= 01111111B, (C) <= 1,
81
И1.00062-01 35 01 M
40. Команда S E T B
40.1. По команде S E T B (табл.40) операнд-приемник уста-
навливается в состояние "1".
Если в качестве операнда-приемника используется бит регистра
специальной функции PSW.0, PSW.2, PSW.6 или PSW.7, то соответст-
вующий триггер признака результата (P), (OV), (AC) или (C) ус-
танавливается в состояние "1".
Т а б л и ц а 40
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11010011 !SETB C !(C) := 1 ! 1
! ! !
11010010 !SETB <BIT> !(I...I) := 1 ! 1
IIIIIIII ! ! !
! ! !
Примеры выполнения команды:
;(P1) = 00000000B
Метка: SETB P1.6
;(P1) <= 01000000B
41. Команда S J M P
41.1. По команде S J M P (табл.41) осуществляется безуслов-
ный прямой переход в точку назначения, расположенную в пределах
от 128 байт, предшествующих коменде, до 127 байт, следующих за
командой, путем сложения текущего содержимого счетчика команд PC
и позиционно-независимого смещения, представленного вторым байтом
кода команды S...S.
Байт позиционно независимого смещения интерпретируется, как
целое число со знаком в пределах от минус 128 до плюс 127.
Т а б л и ц а 40
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
10000000 !SJMP <S> !(PC) := (PC) + 2 ! 2
SSSSSSSS ! !(PC) := (PC) + S...S !
! ! !
Пример выполнения команды:
Цикл: MOV A,R1
;цикл = 0125H
...
ORG 0150H
;S...S=цикл-($+2)=0125H-(0150H+2)=-2DH
Метка: SJMP цикл (т.е. 0D3H)
;(PC) <= (PC) + 2 = 0150H + 2 = 0152H
;(PC) <= (PC) + S...S = 0152H + (-2DH) = 0125H
82
И1.00062-01 35 01 M
42. Команда S U B B
42.1. По команде S U B B (табл.42):
Операнд-источник и бит признака переноса вычитаются из со-
держимого аккумулятора;
Результат записывается в аккумулятор.
Триггеры признаков результата (C), (AC), (OV) и (P) устанав-
ливаются в соответствии с п. 1.7 настоящего приложения.
Т а б л и ц а 42
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
10011RRR !SUBB A,<R> !(A) := (A)-(C)-(RRR) ! 1
! !(C),(AC),(OV),(P) := 0|1 !
! ! !
1001011R !SUBB A,@<R> !(A) := (A)-(C)-((R)) ! 1
! !(C),(AC),(OV),(P) := 0|1 !
! ! !
10010100 !SUBB A,#<D> !(A) := (A)-(C)-D...D ! 1
DDDDDDDD ! !(C),(AC),(OV),(P) := 0|1 !
! ! !
10010101 !SUBB A,<B> !(A) := (A)-(C)-(B...B) ! 1
BBBBBBBB ! !(C),(AC),(OV),(P) := 0|1 !
! ! !
Пример выполнения команды:
;(A) = 0C9H, R2 = 54H, (C) = 1
Метка: SUBB A,R2
;(A) <= 0C9H - 1 - 54H = 74H
;(C) <= 0, (AC) <= 0, (OV) <= 1, (P) <= 1
43. Команда S W A P
43.1. По команде S W A P (табл.43) разряды 0-3 и 4-7 акку-
мулятора обмениваются содержимым, т.е. Содержимое аккумулятора
циклически сдвигается на четыре двоичных разряда.
Триггер признака переноса (P) устанавливается в соответствии
с п. 1.7 настоящего приложения.
Т а б л и ц а 43
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11000100 !SWAP A !(TMP) := (A[3-0]) ! 1
! !(A[3-0]) := (A[7-4]) !
! !(A[7-4]) := (TMP) !
! !(P) := 0|1 !
! ! !
Пример выполнения команды:
;(A) = 00001111B
Метка: SWAP A
;(A) <= 11110000B
83
И1.00062-01 35 01 M
44. Команда X C H
44.1. По команде X C H (табл.44) в аккумулятор пересылается
операнд-источник и одновременно на место операнда-источника пере-
сылается первоначальное содержимое аккумулятора.
Триггер признака четности (P) устанавливается в соответствии
с п. 1.7 настоящего приложения.
Т а б л и ц а 44
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
11001RRR !XCH A,<R> !(TMP) := (A) ! 1
! !(A) := (RRR) !
! !(RRR) := (TMP) !
! !(P) := 0|1 !
! ! !
1100011R !XCH A,@<R> !(TMP) := (A) ! 1
! !(A) := ((R)) !
! !((R)) := (TMP) !
! !(P) := 0|1 !
! ! !
11000101 !XCH A,<B> !(TMP) := (A) ! 1
BBBBBBBB ! !(A) := (B...B) !
! !(B...B) := (TMP) !
! !(P) := 0|1 !
! ! !
Пример выполнения команды:
;(R0) = 20H, (A) = 3FH, ((R0)) = 75H
Метка: XCH A,@R0
;(A) <= 75H, ((R0)) <= 3FH
;(P) <= 0
45. Команда X C H D
45.1. По команде X C H D (табл.45) разряды 0-3 ячейки внут-
ренней памяти данных, адрес которой находится в рабочем регистре
R0 или R1, и аккумулятора обмениваются содержимым (содержимое
4-7 разрядов ячейки памяти и аккумулятора не изменяется).
Триггер признака четности (P) устанавливается в соответствии
с п. 1.7 настоящего приложения.
Т а б л и ц а 45
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
1101011R !XCHD A,@<R> !(TMP) := (A[3-0]) ! 1
! !(A[3-0]) := ((R[3-0])) !
! !((R[3-0])) := (TMP) !
! !(P) := 0|1 !
! ! !
84
И1.00062-01 35 01 M
Пример выполнения команды:
;(A) = 55H, (R0) = 20H, ((R0)) = 0FFH
Метка: XCHD A,@R0
;(A) <= 5FH, ((R0)) <= 0F5H
46. Команда X R L
46.1. По команде X R L (табл.46):
Операнд-источник складывается по модулю 2 с операндом-прием-
ником;
Результат записывается на место операнда-приемника.
Если в качестве операнда-приемника используется содержимое
аккумулятора, то триггер признака четности (P) устанавливается в
соответствии с п. 1.7 настоящего приложения.
Т а б л и ц а 46
-----------------------------------------------------------------
код !инструкция !алгоритм !время
-----------------------------------------------------------------
! ! !
01101RRR !XRL A,<R> !(A) := (A) и не (RRR) или ! 1
! ! Не (A) и (RRR) !
! !(P) := 0|1 !
! ! !
0110011R !XRL A,@<R> !(A) := (A) и не ((R)) или ! 1
! ! Не (A) и ((R)) !
! !(P) := 0|1 !
! ! !
01100100 !XRL A,#<D> !(A) := (A) и не D...D или ! 1
DDDDDDDD ! ! Не (A) и D...D !
! !(P) := 0|1 !
! ! !
01100101 !XRL A,<B> !(A) := (A) и не (B...B) или ! 1
BBBBBBBB ! ! Не (A) и (B...B) !
! !(P) := 0|1 !
! ! !
01100010 !XRL <B>,A !(B...B) := (B...B) и не (A) ! 2
BBBBBBBB ! ! Или не (B...B) и (A) !
! ! !
! ! !
01100011 !XRL <B>,#<D> !(B...B):=(B...B) и не D...D ! 2
BBBBBBBB ! ! Или не (B...B) и D...D !
DDDDDDDD ! ! !
! ! !
Примеры выполнения команды:
;(P1) = 01010101H
Метка: XRL P1, # 00001111H
;(P1) <= 01011010H
85
И1.00062-01 35 01 M
-----------------------------------------------------------------
Лист регистрации изменений
-----------------------------------------------------------------
номера листов (страниц) !всего !номер !вх.Номер!подп.!дата
------------------------------листов!докумен-!сопрово-! !
изм!изме-!заме-!новых !анули-!(стра-!та !дитель- ! !
!нен- !нен- ! !рован-!ниц) в! !ного до-! !
!ных !ных ! !ных !докум ! !кум. И ! !
! ! ! ! ! ! !дата ! !
-----------------------------------------------------------------
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
! ! ! ! ! ! ! ! !
-----------------------------------------------------------------