Из комментариев, приведенных в листинге, можно понять логику формирования задержки, которая составляет 59.821088 с, обеспечивая точность около 0.3 %. И опять же подпрограмму можно дополнить командами nор. Каждая команда пор, помещенная после первого decfsz, добавляет 250 х 240 = 60 000 циклов, так что, вставив три таких команды, мы вместо недостачи получим перебор на 1088 циклов, что даст нам точность не хуже +0.02 %.
Напишите подпрограмму для преобразования однобайтного значения, передаваемого через рабочий регистр, в BCD-число, разряды которого будут находиться в регистрах HUNDRED (h’30’), TENS (h’31’) и UNITS (h’32’).
Решение
Мы уже встречались с процедурой преобразования двоичных чисел в двоично-десятичные в Примере 5.3, приведенном на стр. 159. Однако эта подпрограмма могла преобразовывать только числа из диапазона 0…99, т. е. имеющие два разряда. Тем не менее мы можем воспользоваться примененной в той подпрограмме методикой, вычитая сначала сотни и подсчитывая их число. После этой операции остаток будет меньше 100, и остальная часть подпрограммы будет в точности соответствовать исходной. Полный текст новой подпрограммы, приведенный в Программе 6.11, реализует следующий алгоритм:
1. Разделить на 100; остаток — число сотен.
2. Разделить частное на 10; остаток — число десятков.
3. Частное — число единиц.
; ************************************
; * ФУНКЦИЯ: Преобразовывает число из W в три BCD-разряда *
; * ПРИМЕР: Вход = h’FF’ (d’255’), HUNDREDS = h’02’ *
; * TENS = h’02’, UNITS = h’05’ *
; * ВХОД: W — исходное число *
; * ВЫХОД: HUNDREDS = число сотен, TENS = число десятков *
; * UNITS = число единиц. W — также число единиц *
; *************************************
; Сначала делим на 100
BIN_2_BCD clrf HUNDREDS; Обнуляем счетчик сотен
LOOP100 incf HUNDREDS,f; Запоминаем очередное вычитание
addlw -d’100’; Вычитаем сотню
btfsc STATUS,С; ЕСЛИ заем (С == 0), ТО выходим из цикла
goto LOOP100; ИНАЧЕ вычитаем дальше
decf HUNDREDS,f; Корректируем лишнее вычитание,
addlw d’100’; прибавляя 100 к остатку
;Затем делим на 10
clrf TENS; Обнуляем счетчик десятков
LOOP10 incf TENS,f;Запоминаем очередное вычитание
addlw -d’10’;Вычитаем 10
btfsc STATUS,С;ЕСЛИ заем (С == 0), ТО выходим из цикла
goto LOOP10; ИНАЧЕ вычитаем дальше
; Берем остаток — число единиц
decf TENS,f; Корректируем лишнее вычитание,
addlw d’10’; прибавляя 10 к остатку
movwf UNITS; Получая в результате число единиц,
return; выходим из подпрограммы
Напишите подпрограмму для вычисления квадратного корня из 16-битного целого числа, размещенного в регистрах h’26’:h’27’. Результат должен возвращаться в рабочем регистре.
Решение
Самый примитивный способ решения этой задачи будет заключаться в простом переборе всех целых чисел
Таким образом, возможная структура нашей подпрограммы будет следующей:
1. Сбросить счетчик цикла.
2. Задать переменную
3. ВЫПОЛНЯТЬ бесконечно:
а) Вычесть
в) ИНАЧЕ инкрементировать счетчик цикла.
г) Прибавить 2 к
Вернуть значение счетчика цикла, равное √Number.