Ассемблер (ASM) для AVR в вопросах и ответах

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Мелкие вопросы по теории

Сообщение Мikа »

Спасибо. И ещё вопрос по этому же куску пограммы. Автор статьи, как я понял, дядя Серёжа, пишет, что лучше использовать минимальное количество РОН и если что - обращаться в оперативку.

В этом куске программы регистр, названный Temp1 используется дважды. Первый раз он он добавляет 0 в старший байт регистровой пары Z, то есть в ZH. Потом через него выводят значение R0 на PORTB. Но из-за этого в середине программы, каждый новый цикл, приходится записывать в Temp1 0. Но ведь можно вынести ldi Temp1,0 за метку чтения массива и выполнять это действие только 1 раз. А внутри этой части добавить новый регстр, например, Temp2 и его использовать для записи R0?

Вопрос в следующем. Что лучше, использовать на один РОН больше и избавиться от лишней строчки или же делать как здесь?

UPD: Поскольку сообщение перешло на новую страницу, для удобства дублирую сюда кусок программы.

ldi Temp,0 ;инициализация регистра
;внутренней адресации массива

ReadArray:
ldi ZH,High(MyArray*2) ;загрузка адреса 0-го
ldi ZL,Low(MyArray*2) ;элемента в рег. пару Z

ldi Temp1,0
add ZL,Temp ;прибавление
adc ZH,Temp1 ;внутр. адреса


lpm ;загрузка из ПЗУ

mov Temp1,R0 ;копирование
out PortB,Temp1 ;вывод в порт
inc Temp ;увелич. внутр. адреса
rjmp ReadArray ;в начало цикла

MyArray:
.db 12,16,3,4,10,17,255,37,158,14,13,98
.db 14,85,30,9,145,52,64,49,119,72,209,46

Взято здесь
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Реклама
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Мелкие вопросы по теории

Сообщение Gudd-Head »

Мikа писал(а):Что лучше, использовать на один РОН больше и избавиться от лишней строчки или же делать как здесь

Лучшее враг хорошего. Как вам удобней в конкретной программе, так и делайте.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Мikа »

И ещё один вопрос по коду, взятый из этой статьи:

Теперь в этот кусок мы допишем две строки (перед вызовом задержки):


in Temp,PinD ;читаем порт D

sts Line,Temp Temp ;записываем прочитанное в ОЗУ


Temp, который выделен здесь не лишний? И если нет, то почему?

И ещё 2 вопроса по коммандам, которые применены в цикле задержки:

Delay1:
;цикл задержки

push Temp1
push Temp2


ldi Temp1,0
ldi Temp2,50

d11: dec Temp1
brne d11
dec Temp2
brne d11

pop Temp2
pop Temp1

ret
.

Соттветственно push и pop. Как их понимать и почему их используют здесь, если раньше обходились без них?

Взято здесь.

З.Ы. Я гуглил этот вопрос, но описания команд, которые я находил для меня звучат абсолютно непонятно.
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ploop »

Temp, который выделен здесь не лишний? И если нет, то почему?

Лишний. Опечатка видимо.
Как их понимать и почему их используют здесь, если раньше обходились без них?

Можно вообще обойтись без них (особенно на МК без ОЗУ, только с техническим стеком, необходимым для выхова подпрограмм). Но с ними удобнее.
Что именно непонятно?
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Мikа »

Цитата о PUSH

PUSH Размещение в стеке
Синтаксис: [label] PUSH
Операнды: Нет
Операция: (PC + 2) -> TOS
Изменяет флаги: Нет
Код: 0000 0000 0000 0101
Описание: Данная команда помещает на вершину стека (TOS) значение PC+2. Предыдущее значение, находящееся на вершине стека перемещается на один уровень вниз.
Слов: 1
Циклов: 1
Разбивка по тактам:
Т1 Т2 Т3 Т4
Детектирование команды Запись в TOS, PC+2 Нет операции Нет операции
Пример #1: PUSH
Перед выполнением: TOS = 00345Ah
PC = 000124h
После выполнения: PC = 000126h
TOS = 000126h
Stack (1 уровень вниз) = 00345Ah


Например, что такое PC+2. Дальнейшее непонимание, видимо, появилось из-за того, что увидев описание про СТЕК, я вообще не понял, зачем здесь нужно про него вспоминать.

С POP аналогично. Просто не понимаю, причём здесь вообще стек.

Вообще я уже торможу. Сегодня весь день разбираю эти статьи про огонёк. В смысле читаю не первый раз, просто уже вникаю во всё до последней строчки. Всё было понятно, пока не дошёл до статьи про кнопки. Одни и те же переменные постоянно ссылаются на функции, там их изменяют, возвращаешься обратно, уже забыл, что НА ЭТОТ РАЗ значит эта переменная. Походу, передохнуть надо :)
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Реклама
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Так. Я уже начал сомневаться что у вас АВР.
Но стек-то, думаю, у всех одинаково работает.
Итак, вам надо сохранить значение РОН в ОЗУ на время выполленения подпрограммы (ПП), т.к. в ПП он у вас используется (например, в обработчике прерывания). Проще всего это сделать через стек. Стэк — FIFO регистр. Всего одной командой PUSH вы сохраняете байт в стэке, а на самом деле из указателя стэка (SP) извлекается адрес текущей (свободной) ячейки ОЗУ, по этому адресу сохраняется ваш РОН, значение указателя инкрементируется/декрементируется (SP=SP±1). Всё это вы можете делать и вручную, но зачем?
После выполнения ПП вы восстанавливаете значение РОН командой POP.

Другой вариант действий: в теле основной программы вы НИГДЕ и НИ РАЗУ не используете какой-то РОН, а используете его только в ПП.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ploop »

Например, что такое PC+2

PC - это счётчик команд. Он указывает на адрес той команды, которая непосредственно выполняется. Соответственно PC+2 - следующая команда (адресация у нас двухбайтная).
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

ploop писал(а):PC+2 - следующая команда (адресация у нас двухбайтная).

РС+2 — это не следующая, а команда через одну. Адресация двухбайтная, поэтому нет смысла чтобы счётчик тикал через 2.
Циклов: 1

У АВР операции со стеком длятся 2 такта.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ploop »

Да, точно.
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Мikа »

Спасибо, парни. Про стек я знал - как раз вчера вечером очередной раз читая эти статьи именно ПОНЯЛ, что это такое :) Но вышенаписанное - просто офигенная шпоргалка, её стоит сохранить! Но какова их роль в цикле задержки? Зачем вообще обращаться к стеку? У нас в начале программы Temp1 и Temp2 заменяют имена каких-то регистров. В них пишется число, которое каждый новый цикл уменьшается и проверяется на условие "если не 0, то". Всё это происходит в пределах одного цикла. rcall здесь нет. Причём здесь стек? Оо Вообще не догоняю :shock:

И да, по поводу НЕ АВР. Все примеры, которые я показал, взяты из статьи про реализацию "Бегущего огонька" на МК AVR 90s2313 =) так что тут всё точно про него. Единственное что - это справки, которые я на хожу в интернете. Не факт, что всё про АВР. Но то, что я нашёл - там в заглавии страницы имеется AVR ) Сам собирать макетную плату я буду на следующей неделе, когда всё необходимое будет на столе :)
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Мikа писал(а):Всё это происходит в пределах одного цикла. rcall здесь нет.

Зато rcall есть при вызове вашей процедуры Delay1. И сохраняя/восстанавливая значения изменяемых переменных в процедуре вы можете быть уверены, что вызываемая процедура их не изменит. Если, конечно, у вас стек не переполнится :)
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ploop »

У вас в подпрограмме задержки изменяются значения регистров temp1 и temp2. То есть, вызвав её из основной программы, если вдруг в них что-то было, это потеряется. Чтобы этого избежать, можно:
1. Использовать другие регистры
2. Временно сохранить значение в память, и потом вернуть их в регистры при выходе

1 вариант не годится, т.к. никаких регистров не хватит для более-менее серьёзной задачи. А второй вариант показан: сохраняем значение в стек, используем регистр как угодно, и восстанавливаем его при выходе.

Удобство заключается в том, что при сохранении в память вручную нам пришлось бы всегда следить, куда мы записываем значение регистра. Чтобы записать второй регистр, надо записать его в свободную ячейку, т.е. где-то держать указатель на память, увеличивать/уменьшать, короче геморрой. А тут всё происходит автоматически.
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Мikа »

Вразумили!

Самоконтроль: (если отбросить все подробности)

Если написать push Temp1, то программа сохрание значение Temp1 в ОЗУ.

После этого что бы ни делали с Temp1, значение, сохзранённое в ОЗУ командой push не изменится.

Если написать pop Temp1, порграмма возьмёт из ОЗУ ранее сохранённое значение Temp1, и присвоит его соответственно в Temp1.

Я всё праивльно понял? Не сочтите, что я тупой или слишком дотошный. Просто из-за мелочей (типа два раза Temp выше), всё в голове путается и куча времени тратится. Хочется нормально понять, уяснить, получить "ОДОБРЕНО" от людей знающих и больше к изучению данного вопроса не возвращаться :)

Да, вот ещё вопрос возник. После исполнения команды pop, то что было в ОЗУ затирается? Или в любой момент можно ещё раз написать pop Temp1 и получить в Temp1 то сохранённое значение?
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Gudd-Head »

Всё верно.
Мikа писал(а):После исполнения команды pop, то что было в ОЗУ затирается? Или в любой момент можно ещё раз написать pop Temp1 и получить в Temp1 то сохранённое значение?

То что было в ОЗУ не затирается. Но вот счётчик указателя стэка меняется. Прежде чем ещё раз написать pop Temp1 надо вернуть на нужное место указатель стека. А для этого его надо вытащить из РВВ в РОН. А для этого нужно куда-то сохранить этот РОН :)))
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ploop »

Можно ещё так:

Код: Выделить всё

push Temp1
pop Temp2

В этом случае содержимое Temp1 скопируется в Temp2 через память.

Только осторожнее: сколько push, столько должно быть и pop, иначе получите нехилую такую утечку памяти.
Аватара пользователя
Мikа
Потрогал лапой паяльник
Сообщения: 343
Зарегистрирован: Пн апр 01, 2013 15:13:40
Откуда: Москва

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Мikа »

Спасибо большое! Про утечку памяти уже спрашивать сейчас не буду, маловато свободных килобайт в голове, после прочтения и усвоения всего сегодняшнего :)
Почему я здесь и задаю тупые вопросы?
Потому что хочу научиться.
Аватара пользователя
unalex
Мучитель микросхем
Сообщения: 424
Зарегистрирован: Сб авг 25, 2007 22:02:05
Откуда: Германия, Viernheim

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение unalex »

ploop писал(а):сколько push, столько должно быть и pop


...причем в правильной последовательность(последний вошел, первый вышел)

Код: Выделить всё

   ;Save r17, r18
   push r17
   push r18
   .....
   .....
   ;Restore r18, r17
   pop r18
   pop r17
Коктейль "Рекурсивный": 20% спирта, 30% воды, 50% коктейля "Рекурсивный"...
Аватара пользователя
ploop
Модератор
Сообщения: 13490
Зарегистрирован: Ср ноя 26, 2008 16:34:25
Откуда: Тамбовская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение ploop »

Это важно только для логики работы программы. А чтобы не было утечек, надо держать указатель стека в сухом прохладном месте.
Аватара пользователя
Coldheart
Прорезались зубы
Сообщения: 244
Зарегистрирован: Пт сен 10, 2010 20:39:32
Откуда: Украина Луганская обл.

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение Coldheart »

Подскажите как установить, сбросить бит в регистры по адресу выше 0х70 ?
Контроллер Мега168
к примеру

Код: Выделить всё

   clr r16
   out TCNT0,r16; все ОК
   
          ldi r16,(1<<OCIE2A)|(1<<OCIE2B)|(1<<TOIE2)
   out TIMSK2,r16; Ругаецоо error: Operand 1 out of range: 0x70

          clr r16
   out TCNT2,r16; Ругаецоо error: Operand 1 out of range: 0xb2



Команда OUT не катит в данном случае!
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

Re: Ассемблер (ASM) для AVR в вопросах и ответах

Сообщение akl »

Да, не катит. Попробуйте в соответствии с DS Изображение
mega168_insrt_set.GIF
Ответить

Вернуться в «AVR»