movlw d’20’; Запишем 20 в W
movwf h’3F’; и скопируем его в регистр h’3F’ — счетчик цикла
; ----------------
LOOP
bcf PORTA,0; Выставим на RAO НИЗКИЙ уровень
nop ; Ждем один машинный цикл
bcf PORTA,0; Выставим на RA0 ВЫСОКИЙ уровень
; -----------------
decfsz h’3F’; Считаем в обратном направлении
goto LOOP; Повторить тело цикла, если не ноль
... ...; ИНАЧЕ выйти из цикла
Первоначальный код, обрамленный комментариями в виде пунктирной линии, завершается командой декрементирования с проверкой, которая обеспечивает выход из цикла при достижении регистром h’3F’ нулевого значения. Обратите внимание на запись d’20’ — так в ассемблере явно указывается десятичное число (см. стр. 267). Эта запись эквивалентна записи h’14’, однако гораздо понятнее программисту. В теле цикла используется только одна команда nop, поскольку дополнительная задержка длительностью в один машинный цикл формируется в результате выполнения команд bcf и bsf.
∙ incfsz
Команда инкрементирования регистра данных и пропуска следующей команды при нулевом результате инкрементирует, а не декрементирует содержимое указанного регистра данных. При переходе содержимого через ноль, т. е. в ситуации h’FC’ —> h’FD’ —> h’FE’ —> h’FF’ —> h’00’, будет пропущена следующая команда. Вернемся к нашему примеру, блок-схема которого показана на Рис. 5.19. Если мы предварительно загрузим в регистр h’3F’ число -20 (h’FC’) и заменим команду decfsz h’3F’,f командой incfsz h’3F’,f, то получим тот же самый результат. Только в этом случае счет будет осуществляться в прямом направлении, а не в обратном.
Рис. 5.19.
Напишите программу для декрементирования 2-байтной переменной, расположенной в памяти данных по адресам h’26’ (старший байт) и h’27’ (младший байт). Помните, что команда decf не влияет на состояние флага переноса/заема.
Решение
Сначала напишем алгоритм:
1. ЕСЛИ младший байт в регистре h’27’ равен нулю, то декрементировать старший байт.
2. ВСЕГДА декрементировать младший байт.
Одна из возможных реализаций этого алгоритма приведена в Программе 5.5. При увеличении разрядности исходного значения до
STATUS ecu 3; Регистр STATUS
Z equ 2; Бит 2 — флаг нуля
MSB equ h’26’; Старший байт
LSB equ h’27’; Младший байт
movf LSB,f; Младший байт равен кулю?
btfcs STATUS,Z; ЕСЛИ нет, ТО пропускаем декрементирование старшего байта
decf MSB,f; ИНАЧЕ декрементируем старший байт
decf LSB,f; Всегда декрементируем младший байт
В некоторых ранних моделях компьютеров для представления двоично-десятичных чисел использовался
Хотя такое представление чрезвычайно неэффективно (используется только 10 из 128 возможных комбинаций), его преимуществом является чрезвычайная простота обнаружения ошибок. Напишите программу для проверки корректности числа, представленного в сдвоенном пятизначном коде и находящегося в регистре h’20’ (полагаем, что старший бит равен нулю). В случае ошибки в рабочий регистр необходимо записать h’FF’, иначе — h’00’.
Решение
Все, что нам нужно сделать, — это распознать ситуацию, когда число установленных битов будет больше или меньше двух. Исходя из этого, составим перечень задач:
1. Подсчитать количество единичных битов в числе.
2. Обнулить W.
3. Если полученное число не равно двум, загрузить h’FF’ в W для индицирования ошибки.