AUGEND_H equ h’20’; Два регистра 1-го слагаемого
AUGEND_L equ h’21’
ADDEND_L equ h’22’; Второе слагаемое
SUM_U equ h’30’; Три регистра суммы
SUM_H equ h’31’
SUM_L equ h’32’
STATUS equ 3 ; Регистр STATUS расположен по адресу h’03’
С equ 0; Флаг переноса — 0-й бит регистра STATUS
; Задача 1 ---------------
DP_ADD
movf AUGEND_L,W; Берем младший байт 1-го слагаемого
addwf ADDEND_L,w; Прибавляем 2-е слагаемое, результат — в W
movwf SUM_L; Помечаем результат в младший байт суммы
; Задача 2 ---------------
movf AUGEiCD_H,w; Берем старший байт 1-го слагаемого
btfsc STATUS, С; Был ли перенос при предыдущем сложении?
addlw 1; ЕСЛИ да, ТО прибавляем единицу
movwf SUM_H; Помечаем в средний байт суммы
; Задача 3 ---------------
clrf SUM_U; Обнуляем старший байт суммы {не влияя ка флаг С)
btfsc STATUS, С; Был ли перенос при предыдущем сложении?
incf SUM_U,f; ЕСЛИ да, ТО старший байт суммы равен 01
... ...
В Программе 5.3 следует обратить внимание на два момента:
1. Ни одна из команд программы, за исключением команд сложения, не влияет на состояние флага С. Благодаря этому флаг С можно проверить с помощью команды btfsc даже через две команды после выполнения операции сложения.
2. Команды, следующие после каждой команды btfsc, имеют отступ на один пробел больше, чем остальные. Увеличенный отступ просто подчеркивает, что выполнение этого блока необязательно, т. е. он может быть пропущен. Ассемблер все эти украшательства игнорирует!
Содержимое любого регистра данных можно увеличить или уменьшить на единицу.
∙ incf
Эта команда увеличивает на единицу содержимое заданного регистра данных, помещая результат либо обратно в исходный регистр, либо в рабочий регистр W.
∙ decf
Эта команда уменьшает на единицу содержимое заданного регистра данных, помещая результат либо обратно в исходный регистр, либо в рабочий регистр W. Например, если в регистре h’26’ было записано число h’64’, то после выполнения команды decf h’26’,f в нем окажется число h’63’.
Если в качестве адресата указать рабочий регистр (decf h’26’, w), то содержимое регистра h’26’ останется равным h’64’, а содержимое рабочего регистра станет равным h’63’.
* * *
Хочу обратить ваше внимание на то, что обе эти команды не влияют на флаг переноса С в отличие от эквивалентных команд прибавления или вычитания единицы[84]. В частности, это означает, что если вы собираетесь инкрементировать 3-байтное число, хранящееся в формате
incf LOWER,f; Прибавим единицу
btfss STATUS,Z; Результат равен нулю?
goto NEXT; ЕСЛИ нет (Z == 0), TO выходим
incf MIDDLE,f; ИНАЧЕ инкрементируем следующий байт
goto NEXT; ЕСЛИ нет (Z == 0), ТО выходим
incf UPPER,f; ИНАЧЕ инкрементируем следующий байт
NEXT
... ...; Прочий код
В приведенном фрагменте инкрементируется самый младший байт, и если он становится равным нулю (h’FF’ —> h’00’), то инкрементируется следующий байт и так далее для всех байтов. Эта последовательность прерывается, если при инкрементировании регистра получается ненулевое значение, например
h’06 FF FE’ h’06 FF FF —> h’07 00 00’.
Возможность сброса либо установки отдельного бита в любом регистре памяти данных очень важна, особенно при изменении различных РСН, управляющих процессором и его периферийными устройствами. Изменяемый регистр можно указать с помощью как прямой, так и косвенной адресации.
∙ bcf
Эта команда позволяет программисту сбросить в 0 любой из восьми битов указанного регистра памяти данных.
∙ bsf