movlw d’20’
; Запишем 20 в Wmovwf 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
; Регистр STATUSZ 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 для индицирования ошибки.