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/2
irtovf TEMP,w; Копируем в W
movwf QUOTIENT; и в QUOTIENT, получаем Q = N/2
bcf STATUS,С; Сбрасываем флаг переноса
rrf TEMP,f; Сдвигаем вправо, получаем N/4
roovf TEMP,w; Копируем в W
subwf QUOTIENT,f; Вычитаем, получаем Q = N*(1/2 — 1/4)
bcf STATUS,С; Сбрасываем флаг переноса
rrf TEMP,f; Сдвигаем вправо, получаем N/8
roovf TEMP,w; Копируем в W
addwf QUOTIENT,f; Складываем, получаем Q = N*(1/2 — 1/4 + 1/8)
bcf STATUS,С; Сбрасываем флаг переноса
rrf TEMP,f; Сдвигаем вправо, получаем N/16
movf TEMP,w; Копируем в W
subwf QUOTIENT,f; Вычитаем, получаем Q = N*(1/2 — 1/4 + 1/8 — 1/16)
bcf STATUS,С; Сбрасываем флаг переноса
rrf TEMP,f; Сдвигаем вправо, получаем N/32
movf TEMP,w; Копируем в W
addwf QUOTIENT,f; Складываем, получаем Q = N*(1/2 — 1/4 + 1/8 — 1/16 + 1/32)
bcf STATUS,С; Сбрасываем флаг переноса
rrf TEMP,f; Сдвигаем вправо, получаем N/64
movf TEMP,w; Копируем в W
subwf QUOTIENT,f; Вычитаем, получаем Q = N*(1/2 — 1/4 + 1/8 — 1/16 + 1/32 — 1/64)
bcf STATUS,С; Сбрасываем флаг переноса
rrf TEMP,f; Сдвигаем вправо, получаем N/128
movf TEMP,w; Копируем в W
addwf 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-байтными временными переменными. Однако это все равно гораздо быстрее, нежели простое сложение в цикле.