\
МИКРОКОНТРОЛЛЕРЫ
\
Хотя это знак по здравому рассуждению находится в самом
последнем,
старшем,
байте числа, мы вообще никак на него
не реагировали при выполнении операций над
младшими
бай-
тами. Впечатление не обманчиво - так оно и есть! Знак числа в
дополнительном коде - скорее дело вкуса, чем объективная
реальность: это одна из особенностей дополнительного кода, к
которой просто надо привыкнуть, т.е. одно и то же число мы
можем рассматривать в дополнительном коде и как
имеющее
знак,
и как
не имеющее его.
Так вот, код 11111111b, который
мы получили при вычитании единицы из нуля, можно рассмат-
ривать как
число со знаком
в бите 7, и в этом случае оно бу-
дет равно -1, и, в то же время, как
число без знака
- и в этом
случае оно будет равно 255! Ну а при вычитании единицы из
255 мы рано или поздно доберемся до нуля - тут уж к бабке не
ходи J. Так что флаг S (знак результата) в регистре состояний
процессора говорит всего лишь о том, что в результате опера-
ции мы получили число, в бите 7 которого установлена лог.1. -
и
не более того!
Если есть желание рассматривать это как
знак - пожалуйста! Если нет - тоже флаг в руки!
Вернемся к нашей многострадальной программе, в кото-
рой неожиданно оказалось так много подводных камней. Дос-
читав, наконец, до нуля, очередная команда
subi %а1,1
уста-
новит в регистре состояний процессора флаг Z=1. Для такого
значения флага Z выполнение команды условного перехода
jnz
не предусмотрено - процессор ее просто проигнорирует, и
начнет выполнять вторую команду
subi %а0,1
, непосредствен-
но следующую за проигнорированной
jnz.
В действие вступает
внешний цикл. Обратите внимание
-телом внешнего цикла
является
внутренний цикл
(тело внутреннего цикла, как уже
упоминалось, пустое). Сами команды
subi
и
jnz
не являются
телом цикла, поскольку предназначены не для обработки ин-
формации, а исключительно для организации работы самого
цикла. Как ни дико это звучит - эти команды образуют
заго-
ловок
цикла: в языках программирования высокого уровня
(например, в языке С или Pascal) действия, ими выполняе-
мые, действительно описываются в заголовке цикла, а уж ком-
пилятор с этих языков сам расставляет их в “хвост"’ соответ-
ствующих циклов. Один “оборот"' цикла носит в литературе на-
звание
итерации.
Прикинем, сколько времени будут работать наши циклы.
Внешний цикл будет выполнен 32 раза (20h соответствует чис-
лу 32 в десятичной системе). И на каждой итерации внешнего
цикла внутри него 256 раз будет крутиться внутренний цикл -
именно столько потребуется нашему счетчику, чтобы вернуть-
ся из нулевого значения обратно в нулевое. Всего внутренний
цикл, таким образом, прокрутится 256 • 32 = 8192 раза. А по-
скольку за одну итерацию внутреннего цикла выполняется по
две команды
(subi
и
jnz),
то всего за время работы этих циклов
процессор выполнит более 16 тысяч абсолютно бесполезных
команд (на самом деле их там больше, потому что команды
переходов выполняются вдвое дольше обычных команд, но об
этом разговор впереди). Вот мы и набрали нужное нам число!
Теперь-некоторые пояснения к оставшемуся участку про-
граммы:
4.
“Странная” команда
btgl.
Ее кода нет в описании систе-
мы команд. Дело в том, что даже применение механизма сег-
ментной адресации не сняло проблему нехватки битов для хра-
нения кодов команды, поэтому разработчики микроконтрол-
лера пошли еще на некоторые жертвы, в частности ввели
две
различных команды
для работы с младшей и старшей
46 |-------------------------------------------------------------------------------------------------
тетрадой байта: все
команды
bis, bic, btg
и
btt
существуют толь-
ко с суффиксами I (от английского to w -для младшей тетрады
байта) или
h
(от английского
high
- для старшей тетрады бай-
та). Таким образом, команда
btgl
работает с младшей тетра-
дой регистра порта В (биты 0.
.3). Во втором операнде команды
указывается, какой бит порта надо изменить на противополож-
ный (в данном случае это бит 0). Если бы требовалось изме-
нить на противоположные биты 0 и 2, команда выглядела бы
как
btgl %Ь2,00000101 b
(т.е. мы с помощью единиц отмечаем,
какие биты надо изменять), а если бы требовалось изменить на
противоположные биты 3 и 4, одной командой сделать это мы
бы не смогли: потребовалось бы сначала выполнить команду
btgl %Ь2,00001000b,
а затем команду
btgh %Ь2,00000001Ь
(об-
ратите внимание- не 00010000b, что было бы естественным, а
00000001b: это особенность микроконтроллера КР1878ВЕ1 -
команды с суффиксом
h
считают первым
первый бит своей
тетрады,
а не байта в целом). Ограничения, подобные этим,
встречаются и в других командах, - например, нельзя при сло-
жении и вычитании чисел указывать число более 31 (если нуж-
но прибавить большее число, это число вначале придется за-
писать в какую-нибудь ячейку ОЗУ, а затем сложить нужную
ячейку не с числом, а с той ячейкой, куда вы только что его
записали). Команда
btgl
в данном случае изменит значение
линии В[0] с лог.О на лог.1. При второй итерации цикла она вновь
вернет линию В[0] в лог.О, при третьей - в лог.1 и т.д, обеспечив
таким образом требуемое нам мигание.
5. Еще одна “странная” команда безусловного перехода jmp
передает управление снова на начало циклов. Таким образом
в программе реализован
бесконечный цикл
(напомним, “ми-
галка” должна работать все время, пока включен контроллер).
6. Еще одна “странная” конструкция:
.end.
Это - не коман-
да, а
указание компилятору,
в данном случае-о том, что про-
грамма закончилась. Описание таких указаний есть вдокумен-
тации по КР1878ВЕ1, мы же будем вводить их “в оборот"’ по
мере необходимости.
И еще одна маленькая деталь, касающаяся на этот раз
меток программы. В этом куске программы появились необыч-
ные метки, начинающиеся с символа ($). Это-т.н.
локальные
метки.
Дело вот в чем: для того, чтобы
однозначно
опреде-
лить, на какую команду передать управление, все метки в про-
грамме должны иметь
разные
имена. Меток в хорошей про-
грамме обычно бывает около сотни, и напридумывать им раз-
ные имена оказывается не всегда просто. Локальные метки -
один из способов облегчить эту задачу. Локальные метки мо-
гут быть употреблены между двумя “настоящими” метками,
например так:
l a b e i l: .
.
.
$1:
. . .
$2:
. . .
jmp
$1
jmp
$3
label2: . . .
$1:
. . .
$3:
. . .
I Радиолюбитель - 0 7 /2 0 0 5
предыдущая страница 49 Радиолюбитель 2005-07 читать онлайн следующая страница 51 Радиолюбитель 2005-07 читать онлайн Домой Выключить/включить текст