Главная страница
Библиотека (скачать книги)
Скачать софт
Введение в программирование
Стандарты для C++
Уроки по C#
Уроки по Python
HTML
Веб-дизайн
Ассемблер в среде Windows
ActiveX
Javascript
Общее о Линукс
Линукс - подробно
Линукс - новое
Delphi
Паскаль для начинающих
Турбопаскаль
Новости
Партнеры
Наши предложения
Архив новостей





Ячейки, название которых начинается с BOOT, определяют режим начальной загрузки — как я уже упоминал, в современных AVR можно изменять начальный адрес программы и расположение векторов прерываний. Данные ячейки, как и все остальные, следует оставить как есть. В том числе это касается и битов защиты программы (тех самых "предохранительных", которые здесь называются Boot Lock Bits), которые, к сожалению, настоящей защиты не дают, т. к. легко обходятся. Зато неприятностей могут доставить много, поскольку раз запрограммировав их, исправить что-то уже довольно трудно, а для любителя — почти невозможно.

ГЛАВА 6
Система команд AVR
Познакомившись в предыдущей главе с простейшими программами для AVR, мы теперь попробуем рассмотреть систему команд AVR в целом, чтобы понять, какие возможности нам предоставляются. Всего для AVR насчитывается от 90 до 133 команд (в зависимости от контроллера), и только их подробное описание, например в [2], занимает почти 70 страниц. Потому все команды, которые к тому же часто взаимозаменяемы, мы описывать не будем, для этого существуют справочники. С некоторыми из тех команд, что выпадут из рассмотрения в этой главе, мы познакомимся по ходу дела в дальнейшем. Если будете пользоваться [2], то имейте в виду, что в описаниях команд там встречается несколько мелких, но досадных опечаток (по крайней мере, так было в первом издании), и в критичных случаях нужно проверять по англоязычному фирменному оригиналу. Выборочный перечень команд с их краткой характеристикой, достаточный для составления большинства законченных программ, вы также найдете в приложении 2.

Команды передачи управления и регистр SREG
В языках высокого уровня была всего одна команда перехода на метку (GOTO), и то Дейкстра на нее набросился. А в ассемблере AVR таких команд — пруд пруди, более 30! Зачем? На самом деле без доброй половины из них, если не больше, можно обойтись во всех жизненных случаях, т. к. они в значительной степени взаимозаменяемы. Разнообразие это, если угодно, дань памяти великому программисту — для повышения читаемости программ. Мы рассмотрим только ключевые команды из этого перечня. С командами безусловного перехода rjmp и jmp мы уже познакомились достаточно подробно в предыдущей главе в связи с прерываниями, так что сразу перейдем к вызову процедур (официальный язык атмеловских руководств предпочитает консервативный термин подпрограмма — subroutine) — rcaii и call. Синтаксис у них точно такой же, как у команд безусловного перехода, и по сути это тот же самый переход по метке. И разница между этими двумя командами тоже аналогичная — call работает в пределах 64 К адресов памяти (или до 8 М адресов в соответствующем контроллере, поддерживающем такой объем адресного пространства), занимает четыре байта и выполняется за четыре цикла, a rcall годится только для МК с объемом памяти не более 8 кбайт, но занимает два байта и выполняется за три цикла. Мы в дальнейшем будем пользоваться только командой rcall.

Отличаются они от команд безусловного перехода тем, что здесь в момент перехода к процедуре контроллер автоматически сохраняет в стеке адрес текущей команды, чтобы потом знать, куда вернуться (потому длительность выполнения этих команд на такт больше, чем для простого перехода, см. далее). А как МК "узнает", когда именно нужно возвращаться? Для этого каждая процедура-подпрограмма оформляется специальным образом — не отличаясь сначала ничем от любого другого участка программного кода, обозначенного меткой, в месте возврата она должна содержать специальную команду — ret (от return — "возврат"). По этой команде МК извлекает из стека сохраненное содержимое счетчика команд и продолжает выполнение прерванной основной программы. Аналогично обрабатываются прерывания — только специальной команды, как вы знаете, там нет, вызов производится обычным переходом rjmp или jmp, но поскольку он осуществляется с определенного адреса (там, где стоит вектор прерывания), то контроллер делает то же самое — сохраняет в стеке адрес командного счетчика, на котором выполнение основной программы было грубо нарушено, начинает выполнять прерывание и ожидает команды возврата — только здесь она записывается, как reti (return interrupt) — в отличие от ret, эта команда еще и восстанавливает состояние флага прерываний i в регистре SREG.

В самой обширной группе команд передачи управления названия начинаются с букв br, от слова branch — "ветка". Это команды условного перехода, которые считаются одними из самых главных в любой системе программирования, поскольку позволяют организовывать циклы — базовое понятие программистских наук. По смыслу все эти команды сводятся к банальному if ... then ("если ... то"). Мы будем пользоваться лишь некоторыми командами, потому что они во многом взаимозаменяемы. Смысл остальных вам будет понятен из их описания. Наиболее часто употребляется пара brne (Branch if Not Equal, "перейти, если не равно") и breq (Branch if Equal, "перейти, если равно"). Уже из смысла этих команд понятно, как они пишутся — после команды следует метка, на которую нужно перейти. Вопрос только, откуда здесь берется собственно условие? Для этого эти две команды ветвления обязательно употребляют в паре с одной из команд, устанавливающих флаг нуля z в регистре состояния SREG.

Обычно для этой цели используют команду ср (от compare— "сравнить"), которая сравнивает регистры, или cpi ("сравнить с непосредственным значением"). Для понимания того, что именно при этом происходит, нужно учесть, что данные команды по сути вычитают второй операнд из первого, отличаясь от команд sub или subi только тем, что результат теряется, а операнды остаются теми же, меняются только значения соответствующих флагов регистра SREG, ИЗ которых нас интересуют в первую очередь флаг нуля z, отрицательного значения N и переноса с.

Указанные флаги устанавливаются не только в результате сравнения, но и при выполнении операций с битами или арифметических операций, когда значение результата, соответственно, становится нулевым, отрицательным или превышает диапазон 8-битового числа (255). Что означают флаги регистра SREG в целом, можно посмотреть в табл. 6.1 (на белом фоне находятся флаги, относящиеся к операциям сравнения, а также к арифметическим операциям).



     
 

Библиотека программиста. 2009.
Администратор: admin@programmer-lib.ru