Выбрать главу

3. Старшим байтом суммы является последний бит переноса С2 — 0 или 1 (Рис. 5.10, в).

Поскольку это будет первая программа главы, все операции подробно показаны на Рис. 5.10. Во многих случаях подобная детализация совершенно бесполезна, а алгоритм в виде списка задач может быть дополнен более абстрактной блок-схемой.

Рис. 5.10. Визуализация процесса сложения

Прежде чем перейти к написанию программы, нам необходимо познакомиться с двумя командами (подробно мы их рассмотрим чуть позже). Команда incf позволяет нам непосредственно прибавлять единицу к содержимому любого регистра данных, а команда btfsc проверяет состояние конкретного бита заданного регистра данных и, если этот бит сброшен, выполняет пропуск следующей команды (см. Табл. 5.4). В нашем случае таким регистром является регистр h’03’ (регистр STATUS), а проверяемым битом — бит 0 (флаг переноса), т. е. команда будет записана как btfsc 5,0 или, более понятно, как btfsc STATUS,С. Мы уже использовали аналогичную команду btfss для проверки флага Z в Программе 5.2.

Все три указанные задачи помечены в листинге соответствующими комментариями.

Вводная часть

Всем регистрам с данными присвоены символические имена с помощью директивы equ. Как уже говорилось на стр. 105, использование осмысленных имен вместо голых адресов регистров дает в итоге более удобочитаемую программу. При этом уменьшается вероятность возникновения ошибок и облегчается отладка программы.

Задача 1

Младший байт 1-го слагаемого загружается в W, складывается со 2-м слагаемым, и результат сохраняется в памяти в качестве младшего байта суммы. При этом команда addwf изменяет соответствующим образом состояние флага С. К счастью, на его состояние не влияют последующие команды пересылки.

Задача 2

Старший байт 1-го слагаемого загружается в W. Если бит переноса С1 из предыдущей задачи равен 0, то команда прибавления единицы (addlw 1) пропускается, в противном случае производится инкрементирование содержимого W. Затем результат копируется в средний байт суммы.

Задача 3

Если бит переноса С2 из предыдущей задачи равен 1, то предварительно сброшенный старший байт суммы увеличивается до h’01’. Обратите внимание, что команда clrf SUM_U не воздействует на флаг переноса. Если С2 равен 0, то команда incf SUM_1,f пропускается и старший байт суммы остается нулевым.

Программа 5.3. Выполнение сложения с двойной точностью

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, имеют отступ на один пробел больше, чем остальные. Увеличенный отступ просто подчеркивает, что выполнение этого блока необязательно, т. е. он может быть пропущен. Ассемблер все эти украшательства игнорирует!

Команды инкрементирования и декрементирования

Содержимое любого регистра данных можно увеличить или уменьшить на единицу.