Ревич, Ю.В. Программирование микроконтроллеров AVR: от Arduino к ассемблеру

186 Часть 11. Программирование микроконтроллеров АVR на ассемблере в приведенной директиве . dЬ, нечетное, то последнее выражение будет записано как слово со старшим байтом - последним в ряду, - равным нулю, даже если далее идет еще одна директива . dЬ. Исходя из этого, можно в нужном месте использовать команду lpm следующим хитрым образом (листинг 7 . 1 О) . ldi temp , 5 ; цифра 5 ldi ZH, High (N_mask * 2 ) ; загружаем адрес начала маски ldi ZL , Low (N_mas k* 2 ) add ZL , temp ; адрес маски цифры 5 lpm ; маска окажется в регистре rO ; или так , если цифра - константа : ldi ZH, High (N_mask* 2 ) ; загружаем адрес начала маски ldi ZL , Low ( N_mask* 2 ) subi ZL, -5 ; адрес маски цифры 5 lpm ; маска окажется в регистре rO Здесь в регистр z (и только в z ! ) заносится адрес начала массива констант, причем учитывается, что память программ имеет двухбайтовую организацию, а в z нужно заносить побайтные адреса, отчего появляется множитель 2 . По этому адресу, как мы договорились, располагается маска цифры о. Для загрузки цифры 5 прибавляем к адресу это значение и вызываем команду lpm. Результат окажется в самом первом регистре общего назначения ro, так что при таких действиях его нежелательно за­ нимать под какие-бы то ни было переменные. Команду lpm «понимают» абсолютно все АVR-контроллеры (даже забытого семейства Classic), но МК семейства Mega и многие Tiny (включая ATtiny23 1 3) поддерживают и более понятные форматы команды lpm, аналогичные обычной ld (с любым регистром, необязательно ro, но адресацией также через регистр z ). Примеры этого подхода вы найдете в главе 9 (в программе вывода синуса с помощью ШИМ), а также в главах 13 и 16. Прежде чем перейти к следующей группе команд, следует пару слов сказать об ин­ струкциях работы со стеком push и рор. В других архитектурах (вроде интеловских х5 1 и х86), где регистров общего назначения мало, это едва ли не самые употреби­ тельные команды, т. к. они позволяют не лазать каждый раз в память, что долго, а быстро сохранять промежуточные результаты в стеке и извлекать их оттуда. А здесь мы постараемся ими пользоваться только при необходимости, поскольку использование стека для своих сиюминутных надобностей сильно усложняет логи­ ку программы и служит главным источником трудноотлавливаемых ошибок вре­ мени выполнения (отсылаю любителей всяких финтов опять же к [2] ) . Программа для АVR, где часто встречаются команды push и рор, - верный признак того, что ее автор учился на микроконтроллерах других семейств.

RkJQdWJsaXNoZXIy MTExODQxMg==