QUOTIENT equ h’20’
; Временная переменная для хранения частногоTEMP equ h’21’
; Временная переменная для операций сдвигаSTATUS equ 3
; Регистр STATUSС equ 0
; Бит 0 — флаг перекосаDIV_3 clrf QUOTIENT
; Обнуляем результатmovwf TEMP
; Помещаем N во временный регистрbcf STATUS,С
; Сбрасываем флаг переносаrrf TEMP,f
; Сдвигаем вправо, получаем N/2irtovf TEMP,w
; Копируем в Wmovwf QUOTIENT
; и в QUOTIENT, получаем Q = N/2bcf STATUS,С
; Сбрасываем флаг переносаrrf TEMP,f
; Сдвигаем вправо, получаем N/4roovf TEMP,w
; Копируем в Wsubwf QUOTIENT,f;
Вычитаем, получаем Q = N*(1/2 — 1/4)bcf STATUS,С
; Сбрасываем флаг переносаrrf TEMP,f
; Сдвигаем вправо, получаем N/8roovf TEMP,w
; Копируем в Waddwf QUOTIENT,f
; Складываем, получаем Q = N*(1/2 — 1/4 + 1/8)bcf STATUS,С
; Сбрасываем флаг переносаrrf TEMP,f
; Сдвигаем вправо, получаем N/16movf TEMP,w
; Копируем в Wsubwf QUOTIENT,f
; Вычитаем, получаем Q = N*(1/2 — 1/4 + 1/8 — 1/16)bcf STATUS,С
; Сбрасываем флаг переносаrrf TEMP,f
; Сдвигаем вправо, получаем N/32movf TEMP,w
; Копируем в Waddwf QUOTIENT,f
; Складываем, получаем Q = N*(1/2 — 1/4 + 1/8 — 1/16 + 1/32)bcf STATUS,С
; Сбрасываем флаг переносаrrf TEMP,f
; Сдвигаем вправо, получаем N/64movf TEMP,w
; Копируем в Wsubwf QUOTIENT,f
; Вычитаем, получаем Q = N*(1/2 — 1/4 + 1/8 — 1/16 + 1/32 — 1/64)bcf STATUS,С
; Сбрасываем флаг переносаrrf TEMP,f
; Сдвигаем вправо, получаем N/128movf TEMP,w
; Копируем в Waddwf QUOTIENT,w
; Складываем, получаем N*(1/2 — 1/4 + 1/8 — 1/16 + 1/32 — 1/64 + 1/128)Одной из операций, выполняемой процедурой перевода температуры из шкалы Цельсия в шкалу Фаренгейта, является умножение числа, находящегося в регистре h’22’, на девять. Итоговое 16-битное произведение должно находиться в регистрах h’21’ (старший байт) и h’22’ (младший байт).
Решение
Задачу умножения числа на девять можно разбить на две подзадачи: умножение исходного числа на восемь и прибавление к полученному произведению исходного числа. Соответственно, в Программе 5.9 реализован следующий алгоритм:
1. Умножить число на восемь (сдвинуть 3 раза влево).
2. Добавить исходное число к частичному 16-битному произведению.
Однобайтный множитель копируется в младший байт будущего произведения. Расширение до 16 бит производится обнулением старшего байта произведения. Сбросив флаг переноса и выполнив 3 раза операцию сдвига, получаем частичное произведение исходного числа на 8. И наконец, прибавив однобайтный множитель к двухбайтному частичному произведению, получаем окончательный результат.
Принцип «сдвиг и сложение» (см. стр. 25) может использоваться для реализации умножения любых чисел. Например, умножение на 10 можно реализовать как х8 + х2. Эту операцию запрограммировать немного сложнее, поскольку необходимо оперировать 2-байтными временными переменными. Однако это все равно гораздо быстрее, нежели простое сложение в цикле.