Задача 3
При каждом проходе цикла указатель увеличивается на единицу. Эта операция осуществляется командой incf FSR,f. Обратите внимание, что в качестве адресата указан сам регистр памяти данных, а не рабочий регистр W.
Задача 4
Если вы не собираетесь крутиться в этом цикле бесконечно, то вам потребуется механизм для выхода из него. В нашем случае для этого используется сравнение содержимого регистра FSR с константой h’80’, т. е. адресом первого регистра, находящегося вне заданного диапазона. Сравнение осуществляется копированием содержимого регистра FSR в W (movf FSR,w) и последующим вычитанием рабочего регистра из константы h’80’ с использованием команды addlw — h'80' (прибавление отрицательного числа). Если эти числа равны, то флаг Z будет установлен, в результате чего команда btfss STATUS, Z (см. стр. 133) пропустит следующую за ней команду goto CLOOP. До наступления этого события команда goto будет передавать управление на начало цикла, и процесс будет повторяться с FSR, указывающим наследующий сбрасываемый регистр данных.
В итоге вариант программы с циклом состоит из 8 команд против 96 в линейном варианте, т. е. размер программы уменьшился в 12 раз. Однако наша новая программа выполняется в 7 раз дольше из-за наличия различных команд, необходимых для организации цикла и выполняющихся 96 раз! Обычно затраты на накладные расходы не так велики, как в данном примере.
* * *
Наличие регистра FSR, хранящего адрес операнда, означает, что у нас теперь есть 8-битный изменяемый адрес для обращения к памяти данных вместо фиксированного 7-битного. В свою очередь, из этого следует, что при работе с памятью данных, имеющей два банка (аналогичной приведенной на Рис. 5.3), к любому регистру можно обратиться откуда угодно. Например, если мы хотим записать число b’01111111 в регистр данных h’86’ (регистр специального назначения TRISB, расположенный в 1-м банке), то вместо кода, приведенного на стр. 105, мы можем написать:
movlw h’86’; Настроим FSR для работы
movwf FSR; с регистром h’86’(TRISB)
movlw b01111111; Маска
movwf 0; Записываем ее в указываемый регистр
При этом нам не придется возиться с битом переключения страниц RP0. Если необходимо часто обращаться к какому-либо из регистров первого банка, то можно записать в FSR адрес этого регистра и больше регистр FSR не трогать. Разумеется, предполагается, что он не требуется для других целей[83].
В моделях с четырьмя банками памяти требуется дополнительный бит для образования 9-битного адреса. Бит IRP регистра STATUS, формат которого показан на Рис. 5.5, позволяет косвенно адресовать банки 0/1 (IRP = 0, состояние по умолчанию) и банки 2/3 (IRP = 1). Например, ранее написанный код для копирования содержимого регистра h’120’ банка 2 (PIC16F627/8) в рабочий регистр W, приведенный на стр. 119, можно переписать следующим образом:
bsf STATUS,7; Установим бит IRP (банки 2/3)
movlw h'120'; Инициализируем указатель в FSR
movwf FSR;
rnovf 0,w; Копируем содержимое регистра, указываемого FSR, в W
bcf STATUS,7; Сбрасываем IRP (банки 0/1)
Поскольку в регистре W могут находиться только 8-битные значения, старший бит адреса при выполнении команды movlw h’120’ будет отброшен, т. е. в регистр W будет записано число h’20’. Роль отсутствующего девятого бита выполняет бит IRP, установленный в 1, поэтому обращение произойдет к регистру h’120’, что и требовалось. Ассемблер, возможно, выдаст предупреждение, что в регистр W записывается слишком большое значение. Это предупреждение можно игнорировать.
Четыре команды (на что указывают два бита, помеченные знаками «??») предназначены либо для изменения, либо для проверки состояния отдельных битов в регистре данных. В этом случае в коде команды имеется 3-битное поле NNN, предназначенное для хранения позиции бита (0…7), тогда как адрес регистра кодируется обычным образом. Так, машинный код команды bcf h’20’,7 (сбросить бит 7 в регистре h’20’) выглядит как Ь’0100111010000’. Остальными командами этой группы являются команда bsf (установить бит регистра данных, код 01), btfsc (проверить состояние бита и пропустить следующую команду, если он сброшен, код 10) и btfss (проверить состояние бита и пропустить следующую команду, если он установлен, код 11). Последнюю из перечисленных команд мы уже использовали в Программе 5.2 для проверки 2-го бита регистра h’03’ (т. е. флага Z регистра STATUS) и выходили из цикла, если условие было истинно.
83
В микроконтроллерах старшего семейства имеется три регистра FSR (в действительности реализованные как пара РСН для хранения 12-битного адреса — см. Рис. 16.5 на стр. 579), что упрощает подобное использование этих регистров.