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

Глава 7. Система команд АVR 1 79 либо о, либо 1 - сумма двух восьмиразрядных чисел не может превысить число 5 1 0 (255 + 255), именно потому флаг переноса с представляет собой один­ единственный бит в регистре флагов. Команда brcc (BRanch if Carry Cleared) пред­ ставляет собой операцию перехода по условию, что флаг переноса равен нулю. Таким образом, если флаг не равен нулю, выполнится операция inc RНl - увели­ чение значения регистра RНl на единицу, в противном случае это действие будет пропущено. Можно придумать и другие способы программирования этой опера­ ции. Внимательный читатель, несомненно, уже заметил неточность в программе - а чему равно значение RНl до выполнения нашей процедуры? Вдруг оно совсем не ноль, и тогда нельзя говорить о корректном результате. Поэтому правильней бьmо бы либо дополнить нашу процедуру еще одним оператором, расположив его рань­ ше всех остальных: clr RНl , либо вместо команды inc применить какой-нибудь из способов загрузки значения 1 в переменную RНl (например, ldi RНl , 1 ) . Заметим, что во всех случаях процедура разрастается по времени - было две команды, стало четыре, причем тут имеется замедление еще и неявного порядка: если все представленные арифметические команды выполняются за один такт, то команда ветвления brcc может выполниться за такт (если с = 1 ) , а может и за два (если с = о) . Итого мы выиграли один регистр, а потеряли два или три такта. И так всегда - как мы уже говорили, есть процедуры, оптимизированные по времени, есть - по числу команд, а могут быть - и по числу занимаемых регистров. Идеа­ ла, как и везде в жизни, тут не добиться, приходится идти на компромисс. Если вы посмотрите на сводную таблицу команд в руководствах, то можете обра­ тить внимание, что из восьмибитовых арифметических операций с константой дос­ тупно только вычитание ( suЬi, sbci ) , напрашивающейся же операции сложения с константой нет. Ограничение легко обходится вычитанием отрицательного числа: команда suЬi ternp, - 1 0 прибавит 10 к ternp, а пара команд: suЬi ternp , Low ( - 500 ) ; sbci ternpl , High ( - 5 0 0 ) - добавит к двухбайтовому числу ternpl : ternp двухбайтовую константу 50 0 . Кроме того, разработчики семейства АVR решили облегчить жизнь пользователям, добавив для двухбайтовых операций с константами в перечень арифметических команд две очень удобные команды: adiw и sЬiw. Единственный их недостаток ­ работают они только со старшими парами регистров, начиная с r2 4-r2 5 . Три последние пары ( r2 6-r2 7 , r2 B-r2 9 и r30-r 3 1 ) носят еще название х, У и z, и мы их будем «проходить» далее в этой главе - они задействованы в операциях обмена данными с памятью, так что операции adiw / sЬiw явно нацелены на манипуляции с адресами в памяти. Но в рассматриваемом случае точно так же работает и пара r2 4-r2 5, которая более нигде вместе не употребляется, и это бывает очень удобно. Независимо от используемой пары, старшим регистром считается тот, что с боль­ шим номером, а операцию нужно проводить с младшим, при этом перенос учтется автоматически. Например, в результате выполнения последовательности команд: clr r25 ldi r2 4 , 1 00 adiw r24 , 2 0 0

RkJQdWJsaXNoZXIy MTExODQxMg==