RAIDER писал(а):Не стал создавать новую тему так как я тоже начинающий и возник вопрос с асемблером. Написал программку где в главной функции вызываются по очереди 2 функции. Проще говоря вызывается функция моргают 2 светодиода, вызывается другая то там один загорится другой потухнет и так далее. Но почему то он после вызова первой функции не переходит ко второй.
Пробежал глазами по коду... Ошибка в программе.
Обратите внимание, что сначала записываете в temp2 значение 5, затем вызываете функцию Run2, где затираете temp2 значением 10. Далее крутите цикл до нуля в temp2. Затем возврат из подпрограммы, декремент temp2 (теперь там FF) и проверка флага Z, который при таком раскладе никогда не установится.
"Никогда не опускайся чего б тебе ни стоило, как бы ни было плохо.
А если отступил и сдал немного, то, считай, душа продалась и сдохла!
Честь и кровь - сохрани свою совесть, свобода и любовь - вот она русская гордость"
RAIDER, или внимательней используйте регистры, или используйте их разные. Если не хватает - используйте стек в подпрограммах (push/pop) для временного хранения значений.
Да, и подпрограммы используйте только в том случае, если код повторяется более одного раза. Ну потренироваться конечно можно, но просто это лишнее использование стека и тактов процессора.
используйте стек в подпрограммах (push/pop) для временного хранения значений.
Однако надо помнить, что при входе в подпрограмму на вершине стека будут лежать два байта адреса возврата, а потом - параметры. Так что сначала надо выбрать адрес возврата, потом параметры, а потом положить адрес возврата на место.
Для начала можно просто не забывать в конце подпрограммы извлекание впихнутого назад.
На вершине останется адрес возврата. Команда ret уже им займется.
I am DX168B and this is my favourite forum on internet!
YS, зачем так? Принцип такой, как и в обработчиках прерываний: сохраняем только то, с чем работаем внутри подпрограммы (в прерываниях еще и SREG сохранять надо не забывать)
...
...
;активно работаем с R16, R17
...
...
rcall SubRoutine
...
...
;активно работаем с R16, R17
...
...
SubRoutine:
push R16
push R17
; делаем своё дело
pop R17
pop R16
ret
А, вон ты про что!
Можно, конечно, и через стек перекидывать, но я бы использовал либо регистры, либо через ячейку памяти. Через стек запутано получается.
Дело в том, что при вызове подпрограммы мы точно знаем, где и что у нас лежит. Бери и пользуйся.
RAIDER писал(а):А еще есть вопрос как сделать чтоб светодиод плавно загорался и плавно потухал. В какую сторону идти.
... в сторону ШИМ. Разберись что такое прерывания и вперед. (Хотя можно сделать и на обычных задержках)
PS ... на ассемблере пишут желая получить компактный и быстрый код. Если не имеешь четкого представления, что делает каждая часть программы, то когда ее размер перевалит за 500...1000 строк - желание писать и отлаживать такую программу быстро пропадает.
ploop писал(а):Да, и подпрограммы используйте только в том случае, если код повторяется более одного раза.
Необязательно =)
Меня например учили в универе, что для читабельности кода не нужно городить подпрограмму на 1000 строк. Можно её разбить на функциональные части и оформить ввиде отдельных подпрограмм. Согласитесь, что анализировать код в 20 строк с вызовами rcall гораздо легче, чем сплошной поток команд строк на 200.
"Никогда не опускайся чего б тебе ни стоило, как бы ни было плохо.
А если отступил и сдал немного, то, считай, душа продалась и сдохла!
Честь и кровь - сохрани свою совесть, свобода и любовь - вот она русская гордость"
А меня учили в универе, что суперортикон - современная и перспективная передающая трубка.
Вызовы подпрограмм/возвраты из них отнимают такты. А бывают случаи, когда на счету каждая сотня наносекунд. Кстати, умные компиляторы языков высокого уровня по-возможности вставляют код функции прямо в место вызова. А если объявить ее как inline, то и вообще всегда.
Согласитесь, что анализировать код в 20 строк с вызовами rcall гораздо легче, чем сплошной поток команд строк на 200.
Лучше всего писать комментарии. Для программ на ассемблере это просто жизненно необходимо.
Ассемблер просто необходим для обучения. Только он даст понимание происходящих процессов.
+10^9
Можно, конечно, и через стек перекидывать, но я бы использовал либо регистры, либо через ячейку памяти. Через стек запутано получается.
Да я тоже чаще через регистры перекидываю (в основном из соображений экономии времени). Но если уж заговорили про стек...
Разница между теорией и практикой на практике гораздо больше, чем в теории.
YS писал(а):Вызовы подпрограмм/возвраты из них отнимают такты. А бывают случаи, когда на счету каждая сотня наносекунд. Кстати, умные компиляторы языков высокого уровня по-возможности вставляют код функции прямо в место вызова. А если объявить ее как inline, то и вообще всегда.
Лучше всего писать комментарии. Для программ на ассемблере это просто жизненно необходимо.
Это, скорее, вопрос выбора аппаратных средств, либо работа на пределе возможностей.
И, кстати, через полгода будет трудно вспомнить назначение какого-то куска кода даже с комментариями, либо нужно в комментариях писать "сочинение". Особенно когда в голове держишь несколько проектов. Правильное построение самой программы не менее важно.
"Никогда не опускайся чего б тебе ни стоило, как бы ни было плохо.
А если отступил и сдал немного, то, считай, душа продалась и сдохла!
Честь и кровь - сохрани свою совесть, свобода и любовь - вот она русская гордость"
Программирование МК и есть работа на пределе возможностей. Ведь цены на них, как и эти самые возможности, кратны степени двойки, поэтому всегда хочется выжать максимум.
Нет, я ничего не имею против правильного и структурированного оформления кода, если есть запас ресурсов. Но это как-то больше к ЯВУ относится, нежели к ассемблеру.
ploop писал(а):Но это как-то больше к ЯВУ относится, нежели к ассемблеру.
Думаю, что и к нему тоже =)
Последний раз редактировалось simpleX Вс янв 23, 2011 17:10:53, всего редактировалось 1 раз.
"Никогда не опускайся чего б тебе ни стоило, как бы ни было плохо.
А если отступил и сдал немного, то, считай, душа продалась и сдохла!
Честь и кровь - сохрани свою совесть, свобода и любовь - вот она русская гордость"
YS писал(а):
Согласитесь, что анализировать код в 20 строк с вызовами rcall гораздо легче, чем Да я тоже чаще через регистры перекидываю (в основном из соображений экономии времени). Но если уж заговорили про стек...
И я задам последний вопрос по стеку.
Сколько байт запихивается в стек при вызовах и прерываниях в виде адреса возврата?
Только младшая часть адреса возврата (1 байт) или весь адрес (2 байта)?
I am DX168B and this is my favourite forum on internet!
Данная и не только эта книги у меня есть. Ну не дружу я с английским
R5VCH
Хотелки:
СпойлерАналоговый осциллограф С1-112, С1-118, другие
не/рабочие модули от комплекса ОДА-102
всё что касается AVR, arduino, raspberry
всё что касается КВ-УКВ-радиосвязи, mashtastic
Сколько байт запихивается в стек при вызовах и прерываниях в виде адреса возврата?
Только младшая часть адреса возврата (1 байт) или весь адрес (2 байта)?