|
|
  |
Ассемблер AVR |
|
|
|
Jul 11 2012, 19:55
|
Группа: Новичок
Сообщений: 2
Регистрация: 11-07-12
Пользователь №: 72 725

|
Не взыщите но глупых вопросов не бывает. Как на ассемблере расшифровать две следующие записи (точне значки << |). 1. 1<<USIOIF 2.( 1<<USIOIF)|( 1<<USICS1) Заранее спасибо.
|
|
|
|
|
Jul 11 2012, 20:23
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(vvvalarm @ Jul 11 2012, 22:55)  Не взыщите но глупых вопросов не бывает. Понять-то не мудрено: Цитата(vvvalarm @ Jul 11 2012, 22:55)  Не взыщите но глупых вопросов не бывает. Как на ассемблере расшифровать две следующие записи (точне значки << |). 1. 1<<USIOIF Где-нибудь в inc-файле (или каком-другом) определена константа USIOIF. Допустим так: Код .equ USIOIF = 6 1<<USIOIF=1<<USIOIF=единица сдвинутая влево на позиция=0x40=40H=64(dec) Цитата(vvvalarm @ Jul 11 2012, 22:55)  2.( 1<<USIOIF)|( 1<<USICS1) ( 1<<USIOIF)|( 1<<USICS1)=(1 сдвинутая влево на USIOIF позиций) логическое ИЛИ с (1 сдвинутая влево на USICS1 позиций)
|
|
|
|
|
Jul 11 2012, 20:33
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Xenia @ Jul 11 2012, 23:22)  Это не ассемблер, а C Нет, вы не правы: это вполне может быть ассембером. IAR AVR ассемблер вполне поймет такое например: Код andi R16, (1<<2) | (1<<7) также как и #if, #define и тд по списку.
|
|
|
|
|
Jul 11 2012, 21:54
|
Гуру
     
Группа: Свой
Сообщений: 2 128
Регистрация: 21-05-06
Пользователь №: 17 322

|
Цитата(Xenia @ Jul 11 2012, 23:42)  Ясное дело - из C спёрли.  Унифицыровали, а не сперли. Цитата(Xenia @ Jul 11 2012, 23:42)  А что это за ассемблер? Вы что-нибудь про IAR слышали? Они выпускают такой продукт: IAR Embedded Workbench for Atmel AVR. Ассемблер бесплатно (может уже и не бесплатно), остальное за деньги. Цитата(Xenia @ Jul 11 2012, 23:42)  AVR Studio или какой-еще? Наверняка также у AVR GCC, AVR assembler v2. Как там у ImageCraftow, и прочих codevison-ов не скажу - не знаю.
|
|
|
|
|
Jul 12 2012, 00:30
|
Местный
  
Группа: Участник
Сообщений: 406
Регистрация: 22-05-11
Из: Москва
Пользователь №: 65 195

|
Как раз сейчас осваиваю не спеша ассемблер AVR. Начитавшись умных и глупых книжек, скажу:
Такое широко используется в ассемблере AVR (в частности, в AVR Studio), чтобы установить нужные биты в разных служебных регистрах. А это всегда требуется при инициализации МК или изменении каких-то режимов (включении-выключении прерываний, интерфейсов и пр.) Поскольку точное положение управляющего бита в служебном регистре не запомнить, да еще в разных МК AVR они могут быть в разных местах, то так и делают, например операция (1<<USIOIF)|(1<<USICS1) дает байт с единицами на месте битов USIOF и USICS1, а остальные нули. Осталось записать этот байт в нужный служебный регистр, ну или сделать операцию ИЛИ, если остальные биты трогать не надо.
Теоретически это улучшает читаемость и (что важно) переносимость программы, поэтому активно рекомендуется так делать.
Разумеется, нужно включить командой .INCLUDE файл, соответствующий данному МК (например "M32DEF.INC"), в котором, как уже писали, этим константам соответствуют некоторые числа. Иначе работать не будет.
|
|
|
|
|
Jul 12 2012, 05:58
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (SmarTrunk @ Jul 12 2012, 03:30)  Теоретически это улучшает читаемость ... программы, поэтому активно рекомендуется так делать. А вы попробуйте написать один проект используя только записи вида CODE UCSR0B = 0x98 вместо CODE UCSR0B = (1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02); Я даже не говорю о том, чтобы что-то исправить в этом проекте через неделю - просто дописать его до конца и отладить. Думаю, вы очень быстро поймете, что такая запись улучшает читаемость не теоретически, а практически.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 12 2012, 08:17
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (ILYAUL @ Jul 12 2012, 09:44)  Мне больше "нравится" когда написано так и по всему коду CODE UCSR0B = 0b10011000 И даже в этом случае невозможно понять, что тут происходит, не заглядывая в даташит. А значит нужно отвлекаться, что совсем не способствует сосредоточенному написанию/отладке программы, даже теоретически. А в процессе написания не защищает от ошибок/описок.
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 12 2012, 11:16
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(ILYAUL @ Jul 12 2012, 10:44)  Мне больше "нравится" когда написано так и по всему коду UCSR0B = 0b10011000 Э! Мне так тоже нравится.  Я в свое время голову ломала - зачем так вычурно биты определены, что каждый раз при их использовании приходится единицу влево сдвигать? А потом догадалась - это особенность специфических команд AVR, работающих с отдельными битами, типа: sbi PORTA, PINA2 cbi PORTA, PINA2 где в качестве аргумента должен быть указан НОМЕР бита, а не маска. В тех архитектурах, где подобных инструкций нет, битовые константы опредяляют, как маски, а единиц не двигают.
|
|
|
|
|
Jul 12 2012, 12:47
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Xenia @ Jul 12 2012, 15:16)  ...это особенность специфических команд AVR, работающих с отдельными битами, типа: sbi PORTA, PINA2 cbi PORTA, PINA2 где в качестве аргумента должен быть указан НОМЕР бита, а не маска.В тех архитектурах, где подобных инструкций нет, битовые константы опредяляют, как маски, а единиц не двигают. долго читал пэйджер, тьху мессагу. что то с точностью да на оборот Вы написали явно. наоборот, единицы двигаются при создании группы бит = масок. когда у нас один бит - то собственно достаточно явно указать бит. правда не все регистры корректно могут воспринимать это (sbi, cbi). и вроде как до вашей мессаги sbi & cbi команды вообще не рассматривались. т.е. речь шла конкретно о сдвиге и всё что вокруг него крутиться. тут наверное ближе слово не архитектура а компилятор. т.к. на выходе (в бинарнике) будет одна сущность = байт, слово, двойное слово и т.д.. а как вы его получили или слепили(можно например умножать в целых числах, или логически объеденять в различных системах счисления) - для железа вовсе фиолетово.
Сообщение отредактировал kolobok0 - Jul 12 2012, 12:52
|
|
|
|
|
Jul 12 2012, 14:06
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(kolobok0 @ Jul 12 2012, 16:47)  долго читал пэйджер, тьху мессагу. что то с точностью да на оборот Вы написали явно. наоборот, единицы двигаются при создании группы бит = масок. когда у нас один бит - то собственно достаточно явно указать бит. правда не все регистры корректно могут воспринимать это (sbi, cbi). и вроде как до вашей мессаги sbi & cbi команды вообще не рассматривались. т.е. речь шла конкретно о сдвиге и всё что вокруг него крутиться. В том-то и дело, что из номеров битов можно состряпать маску (сдвигая ту самую едлиницу), тогда как обратное преобразование арифметическими средствами невозможно. Поэтому, если в хидерах/инклюдах имена битов опредены, как маски, то использовать их в качестве аргументов sbi/cbi будет нельзя. А вот определение их, как номер бита, позволяет делать и то и другое, с теми лишь накладными расходами, что приходится двигать единицу, когда нужна маска. И несмотря на то, что двигается эта единица не в процессе исполнения, а в процесе компиляции, битовые маски, образуемые большим набором битов, выглядят в таком исполнении чудовищно.  А не было бы в инструкциях команд sbi/cbi, но не было бы и проблемы, т.к. ничто не мешало бы перейти на маски.
|
|
|
|
|
Jul 12 2012, 15:27
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(Xenia @ Jul 12 2012, 23:06)  ...обратное преобразование арифметическими средствами невозможно. AVRASM & AVRASM2, установить в "1" бит 5 в регистре R16 и в PORTA. Код .equ MASK = 0b00100000 ORI R16, MASK SBI PORTA, LOG2(MASK)
|
|
|
|
|
Jul 12 2012, 17:18
|
Профессионал
    
Группа: Свой
Сообщений: 1 719
Регистрация: 13-09-05
Из: Novosibirsk
Пользователь №: 8 528

|
Цитата(Xenia @ Jul 12 2012, 23:00)  Ух ты! Не думала, что ассемблер в времени компиляции способен вычислять логарифы. Отпад! Это только называется так круто, а на деле двоичный, де ещё и целочисленный логарифм это и есть номер самого старшего бита в слове. PS. У кортексов, кстати, есть команда CLZ, вычисляющая количество ведущих нулей в слове.
--------------------
Russia est omnis divisa in partes octo.
|
|
|
|
|
Jul 12 2012, 21:56
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Tiro @ Jul 12 2012, 23:41)  А почему Вы не напомнили, что макрос (1<<(x)) давно обозвали BIT(x). Читать совсем удобно. Возможно потому, что я понятия не имею, кто и где его так обозвал. Создатели avr-libc с вами не согласны - они обозвали такой макрос _BV(x). В то время как конструкция (1 <<(x)) совершенно однозначно понимается любым компилятором C, C++, "языков, похожих на C", многими ассемблерами и любым программистом, знающим любой из этих языков.  А еще обратите внимание на приведенную мной запись CODE UCSR0B = (1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02); Здесь совершенно четко видно - какой бит в нуле, а какой - в единице. И чтобы изменить значение бита, достаточно заменить ноль на единицу или наоборот. В случае же BIT(x) или битовых масок придется делать либо (1*BIT(x))|(0*BIT(y)), либо комментировать части выражения. Оба варианта совсем не добавляют читабельности. Еще для сброса бита можно удалять части выражения, но это тоже неудобно, ибо когда понадобится эту часть выражения снова вернуть - в большинстве случаев придется лезть в даташит/заголовочный файл, чтобы уточнить название добавляемого бита. QUOTE (Xenia @ Jul 12 2012, 20:26)  А когда siziof() в хидере не захотел компилить, то я и вовсе разозлилась.  Может быть отказался компилить, потому что на момент обработки этого sizeof размер был неизвестен (incomplete type)? Зачем расходовать нервные клетки? Просто поставьте себя на место компилятора. И на его месте, вероятно, вы бы сказали "Не виноватая я!!!..."
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 12 2012, 22:03
|
Знающий
   
Группа: Свой
Сообщений: 781
Регистрация: 3-10-04
Из: Санкт-Петербург
Пользователь №: 768

|
Цитата(Сергей Борщ @ Jul 13 2012, 00:56)  Создатели avr-libc с вами не согласны - они обозвали такой макрос _BV(x). Да, сорри, запамятовал, _BV Цитата(Сергей Борщ @ Jul 13 2012, 00:56)  Код UCSR0B = (1<<RXCIE0)|(0<<TXCIE0)|(0<<UDRIE0)|(1<<RXEN0)|(1<<TXEN0)|(0<<UCSZ02); Здесь совершенно четко видно - какой бит в нуле, а какой - в единице. И чтобы изменить значение бита, достаточно заменить ноль на единицу или наоборот. В случае же BIT(x) или битовых масок придется делать либо (1*BIT(x))|(0*BIT(y)), либо комментировать части выражения. Для неустановки в 1 достаточно не писать _BV(BIT). Это будет даже нагляднее.
|
|
|
|
|
Jul 13 2012, 00:26
|
;
     
Группа: Участник
Сообщений: 5 646
Регистрация: 1-08-07
Пользователь №: 29 509

|
Цитата(Xenia @ Jul 12 2012, 14:16)  В тех архитектурах, где подобных инструкций нет, битовые константы опредяляют, как маски, а единиц не двигают. Танунет. Это плохая практика, совсем. В смысле портабельности, а чего мы здесь сеголня собрались?  Ассемблер только повод... Цитата(Tiro @ Jul 13 2012, 01:03)  Для неустановки в 1 Всегда говорил, что это идеологиццкая полумера: Раз есть _BV, должен быть и _nBV Код #define _nBV(bit) (~(1<<bit)) //but better #define _nBV(bit) (~_BV(bit))
Сообщение отредактировал _Pasha - Jul 13 2012, 00:32
|
|
|
|
|
Jul 13 2012, 03:11
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(_Pasha @ Jul 13 2012, 09:26)  #define _nBV(bit) (~(1<<bit)) #define _nBV(bit) (~_BV(bit)) _BV(3) | _BV(5) = 0x28 _BV(3) | _nBV(5) = 0xFF вместо ожидаемых: 1<<3 | 1<<5 = 0x28 1<<3 | 0<<5 = 0x08
|
|
|
|
|
Jul 13 2012, 04:02
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Сергей Борщ @ Jul 13 2012, 00:56)  Может быть отказался компилить, потому что на момент обработки этого sizeof размер был неизвестен (incomplete type)? Скорее, было Код #if sizeof(foo) == moo Поскольку sizeof — оператор языка, в препроцессоре он не должен работать.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jul 13 2012, 08:24
|

Гуру
     
Группа: Модераторы
Сообщений: 8 455
Регистрация: 15-05-06
Из: Рига, Латвия
Пользователь №: 17 095

|
QUOTE (Xenia @ Jul 13 2012, 10:57)  уперся рогом. Ксения, вы специально заставляете нас разгадывать, что означает применительно к компилятору "отказался компилировать" и "уперся рогом"? Как объяснил ReAl - MS Visual C/C++ как раз поступил строго по стандарту. То, что Borland C/C++ (и его потомки) скомпилили этот код еще не означает, что он работал именно так, как вы ожидали. Вы проверяли их на "тревожных" входных данных? Тревогу бьют?
--------------------
На любой вопрос даю любой ответ"Write code that is guaranteed to work, not code that doesn’t seem to break" ( C++ FAQ)
|
|
|
|
|
Jul 13 2012, 08:45
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Xenia @ Jul 13 2012, 11:57)  а MS Visual C/C++ уперся рогом. Правильно уперся. Препроцессор не должен знать ничего из языка - он запускается до компилятора, да и ему вообще имеют право подсунуть не С/С++ текст. А для проверки 'во сколько байт компилится' есть другие возможности, чисто компиляторные Код #define STATIC_ASSERT(cond,msg) typedef char _Static_Assert_Typedef_##msg [ (cond)?1:-1];
struct A { int a; int b; };
STATIC_ASSERT(sizeof(struct A) == 8, StructA);
|
|
|
|
|
Jul 13 2012, 10:14
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(XVR @ Jul 13 2012, 12:45)  А для проверки 'во сколько байт компилится' есть другие возможности, чисто компиляторные Код #define STATIC_ASSERT(cond,msg) typedef char _Static_Assert_Typedef_##msg [ (cond)?1:-1];
struct A { int a; int b; };
STATIC_ASSERT(sizeof(struct A) == 8, StructA); Не вижу, чтобы мой метод был сильно хуже: Код #if sizeof(Interface) != 136 #pragma message Bad size of struct Interface #endif
|
|
|
|
|
Jul 13 2012, 10:16
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
да именно статк асерт здесь рулит.
static_assert.rar ( 448 байт )
Кол-во скачиваний: 81to Xenia: конечно ваш код хуже, 3 строки вместо одной... to XVR: не вижу смысла во втором аргументе вашего макроса.
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 13 2012, 10:56
|
Гуру
     
Группа: Свой
Сообщений: 3 123
Регистрация: 7-04-07
Из: Химки
Пользователь №: 26 847

|
Цитата(Xenia @ Jul 13 2012, 14:14)  Не вижу, чтобы мой метод был сильно хуже: Код #if sizeof(Interface) != 136 #pragma message Bad size of struct Interface #endif Он не хуже, он просто не работает нигде, кроме Borland'а  Цитата(demiurg_spb @ Jul 13 2012, 14:16)  to XVR: не вижу смысла во втором аргументе вашего макроса. Это для дополнительной диагностики (для пользователя). Хотя вариант с __LINE__ тоже вполне подойдет
|
|
|
|
|
Jul 13 2012, 11:07
|

Гуру
     
Группа: Модератор FTP
Сообщений: 4 479
Регистрация: 20-02-08
Из: Москва
Пользователь №: 35 237

|
Цитата(demiurg_spb @ Jul 13 2012, 14:16)  to Xenia: конечно ваш код хуже, 3 строки вместо одной... Зато ваш хидер static_assert.h таков, что я в нем ничего не понимаю  . Определяется STATIC_ASSERT_H(expr) с единственным аргументом, а подставляется целых два: STATIC_ASSERT(sizeof(struct A) == 8, StructA); И вообще непонятно, что сделает STATIC_ASSERT, если размер не сойдется. Компиляцию остановит, ошибку выдаст? Цитата(demiurg_spb @ Jul 13 2012, 14:16)  to XVR: не вижу смысла во втором аргументе вашего макроса. Это чтобы нужное сообщение в мессадже среди варнингов появилось. Но можно было бы вместо него и #error использовать.
|
|
|
|
|
Jul 13 2012, 11:45
|

неотягощённый злом
     
Группа: Свой
Сообщений: 2 746
Регистрация: 31-01-08
Из: Санкт-Петербург
Пользователь №: 34 643

|
Цитата(Xenia @ Jul 13 2012, 15:07)  Зато ваш хидер static_assert.h таков, что я в нем ничего не понимаю  . Определяется STATIC_ASSERT_H(expr) с единственным аргументом, а подставляется целых два: STATIC_ASSERT(sizeof(struct A) == 8, StructA); И вообще непонятно, что сделает STATIC_ASSERT, если размер не сойдется. Компиляцию остановит, ошибку выдаст? Так я и говорю, что достаточно одного аргумента. И в самом начале файла static_assert.h есть пример использования для совсем уж непонятливых  Цитата Это чтобы нужное сообщение в мессадже среди варнингов появилось. Но можно было бы вместо него и #error использовать. Излишне это. Выскочит ошибка компиляции, вы и так сразу поймёте, что асерт сработал. В его условии весь смысл обычно и заложен, никаких дополнительных подсказок не требуется, а если не так, то комментарии никто не отменял и ты сам себе Буратино:-)
--------------------
“Будьте внимательны к своим мыслям - они начало поступков” (Лао-Цзы)
|
|
|
|
|
Jul 13 2012, 17:02
|
Группа: Новичок
Сообщений: 2
Регистрация: 11-07-12
Пользователь №: 72 725

|
Цитата(SmarTrunk @ Jul 12 2012, 03:30)  Как раз сейчас осваиваю не спеша ассемблер AVR. Начитавшись умных и глупых книжек, скажу:
Такое широко используется в ассемблере AVR (в частности, в AVR Studio), чтобы установить нужные биты в разных служебных регистрах. А это всегда требуется при инициализации МК или изменении каких-то режимов (включении-выключении прерываний, интерфейсов и пр.) Поскольку точное положение управляющего бита в служебном регистре не запомнить, да еще в разных МК AVR они могут быть в разных местах, то так и делают, например операция (1<<USIOIF)|(1<<USICS1) дает байт с единицами на месте битов USIOF и USICS1, а остальные нули. Осталось записать этот байт в нужный служебный регистр, ну или сделать операцию ИЛИ, если остальные биты трогать не надо.
Теоретически это улучшает читаемость и (что важно) переносимость программы, поэтому активно рекомендуется так делать.
Разумеется, нужно включить командой .INCLUDE файл, соответствующий данному МК (например "M32DEF.INC"), в котором, как уже писали, этим константам соответствуют некоторые числа. Иначе работать не будет. Спосибо Ваше объяснение наиболее мне понятно.
|
|
|
|
|
Jul 14 2012, 10:31
|

Нечётный пользователь.
     
Группа: Свой
Сообщений: 2 033
Регистрация: 26-05-05
Из: Бровари, Україна
Пользователь №: 5 417

|
Цитата(Сергей Борщ @ Jul 13 2012, 09:31)  Э... нет. Вводная была "отказался компилить", а не "компилил неправильно"  Ну это и имелось ввиду — оператора такого для препроцессора нет и он ругается. Цитата(Сергей Борщ @ Jul 13 2012, 11:24)  То, что Borland C/C++ (и его потомки) скомпилили этот код еще не означает, что он работал именно так, как вы ожидали. В Борланде это работающее расширение. ___________________ Borland Users Group == BUG … Неспроста…
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
Jul 26 2012, 00:39
|

Участник

Группа: Участник
Сообщений: 31
Регистрация: 5-04-06
Из: Екатеринбург
Пользователь №: 15 809

|
Как я улучшаю читаемость при установке битов в конфигурационные регистры: MCU.cppПосмотрите в листинге инициализацию всей периферии микроконтроллера. Вот пример: CODE /** * Настройка таймера/счётчика 1 */ void CMCU::Timer1Init(){
// [ATmega16] Table 62. Clock Select Bit Description // +----+----+----+-----------------------------------------------------------------+ // |CSn2|CSn1|CSn0| Description ¦ // +----+----+----+-----------------------------------------------------------------+ // | 0 | 0 | 0 | No clock source. (Таймер/счетчик остановлен) | // | 0 | 0 | 1 | clkI/O/1 (No prescaling) | // | 0 | 1 | 0 | clkI/O/8 (From prescaler) | // | 0 | 1 | 1 | clkI/O/64 (From prescaler) | // | 1 | 0 | 0 | clkI/O/256 (From prescaler) | // | 1 | 0 | 1 | clkI/O/1024 (From prescaler) | // | 1 | 1 | 0 | Вывод Тn, счет осуществляется по спадающему фронту импульсов | // | 1 | 1 | 1 | Вывод Тn, счет осуществляется по нарастающему фронту импульсов | // +----+----+----+-----------------------------------------------------------------+
// Timer/Counter1 Control Register B // [ Регистр управления B Таймером/Счётчиком 1 ][ATmega16] // 00000000 - Initial Value TCCR1B = BIN8(00000000); // BIN8() не зависит от уровня оптимизации // |||||||| // |||||||+- 0, rw, CS10: -+ // ||||||+-- 1, rw, CS11: | - Управление тактовым сигналом // |||||+--- 2, rw, CS12: _| // ||||+---- 3, rw, WGM12: -+ - Режим работы таймера/счетчика // |||+----- 4, rw, WGM13: _| // ||+------ 5, r: 0 - зарезервирован, должен быть установлен в 0 при записи // |+------- 6, rw, ICES1: - Выбор активного фронта сигнала захвата // +-------- 7, rw, ICNC1: - Управление схемой подавления помех блока захвата // Примечание:
// Устанавливаем значения для счётных регистров TCNT1H = 0x00; // ( 0xFFFF - Delay * F_CPU / PrescaleValue ) >> 8 TCNT1L = 0x00; // ( 0xFFFF - Delay * F_CPU / PrescaleValue ) /* OCR1AH = 0x00; OCR1AL = 0x39;
OCR1BH = 0x00; OCR1BL = 0x39;
OCR1CH = 0x00; OCR1CL = 0x39;
ICR1H = 0x00; ICR1L = 0x39; */ // Timer/Counter1 Control Register A // [ Регистр управления A Таймером/Счётчиком 1 ][ATmega16] // 00000000 - Initial Value TCCR1A = BIN8(00000000); // BIN8() не зависит от уровня оптимизации // |||||||| // |||||||+- 0, rw, WGM10: -+ - Режим работы таймера/счетчика // ||||||+-- 1, rw, WGM11: _| // |||||+--- 2, rw, COM1C0: -+ - Режим работы канала сравнения C // ||||+---- 3, rw, COM1C1: _| // |||+----- 4, rw, COM1B0: -+ - Режим работы канала сравнения B // ||+------ 5, rw, COM1B1: _| // |+------- 6, rw, COM1A0: -+ - Режим работы канала сравнения A // +-------- 7, rw, COM1A1: _| // Примечание: Установлен режим работы ...
TCCR1B = BIN8(00000000); // BIN8() не зависит от уровня оптимизации // |||||||| // |||||||+- 0, rw, CS10: -+ // ||||||+-- 1, rw, CS11: | - Управление тактовым сигналом // |||||+--- 2, rw, CS12: _| // ||||+---- 3, rw, WGM12: -+ - Режим работы таймера/счетчика // |||+----- 4, rw, WGM13: _| // ||+------ 5, r: 0 - зарезервирован, должен быть установлен в 0 при записи // |+------- 6, rw, ICES1: - Выбор активного фронта сигнала захвата // +-------- 7, rw, ICNC1: - Управление схемой подавления помех блока захвата // Примечание: Коэффициент деления тактовой частоты установлен равным ... // Режим работы: ...
}
Сообщение отредактировал uni - Jul 26 2012, 03:43
--------------------
Россия навсегда!
|
|
|
|
|
Aug 7 2012, 07:07
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(demiurg_spb @ Aug 7 2012, 10:25)  ...не может исполняться у АВР. ля тех кто читает между строк - краткое содержание преддущих топиков: идёт речь об адресах, которые могут храниться как во флэше так и в озу... адреса переходов, а не код. повнимательней что ли бы... Цитата(ILYAUL @ Aug 6 2012, 21:43)  ...в смысл дизasm не даст ниодной метки переходов, как будто программа выполняется подряд , команда за командой.... кстати по поводу данной мысли. _любой_ бинарный код - команда за командой. в данный момент времени мощные дизасэмблеры отлично орентируются в командах проца, команды которого дезасмблируют. и деление на подпрограммы - есть условности именно дизасэмблера, а не бинарного модуля как такогого. т.е. я о чём - после отработки современного дизасэмблера подпрограммы будут(чисто отмеченные дизасэмблером). а вот очерёдность и порядок вызова данных подпрограмм - вот это уже не будет следовать из кода. и где применимо...наверное там, где прошивка передаётся в открытом виде. но в серъёзных проектах - это не серьёзно(открытая прошивка)
Сообщение отредактировал kolobok0 - Aug 7 2012, 07:09
|
|
|
|
|
Aug 7 2012, 08:41
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Цитата идёт речь об адресах, которые могут храниться как во флэше так и в озу... адреса переходов, Не всем так , нет там адресов переходов ни во FLASH ни в SRAM . Вы можете использовать SRAM по прямому назначению . но это никак не повлияет на адресацию. Все адреса переходов вычисляются на стадии компиляции программы , а использование команды ret вообще для любого диза - просто ret / А вот то , что с этой точки можно уйти в любую сторону кода без последствий , я думаю что он тоже не просечёт. Отслеживать стек , я думаю дизы ещё не научились. Собственно , особо нового ничего и нет. Многим известен такой подход Код ldwi Z,METKA push ZL push ZH ---------- MAIN: Какой -то код ----------- ret Какой -то код ----------- METKA: Это всё в области FLASH , и метка существует в явном виде иначе компилятор ее не вычислит. но если Код .dseg METKA: то адрес метки возьмётся по адресу SRAM Если METKA = 0x100 , то программа удёт на адрес 0x100 , если добавить .byte 8 - то на удёт на 0x108, при этом в самой программе меток нет вообще Код 0x107 ldi count,30 0x108 dec count 0x109 add temp,count 0x110 sts METKA, temp ну и т.д. этот код для примера т.е просто набор пришедших в голову команд
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Aug 7 2012, 11:38
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(ILYAUL @ Aug 7 2012, 12:41)  ...Вы можете использовать SRAM по прямому назначению . но это никак не повлияет на адресацию. Все адреса переходов вычисляются на стадии компиляции программы...Отслеживать стек...такой подход ...Это всё в области FLASH , и метка существует в явном виде иначе компилятор ее не вычислит....адрес метки возьмётся по адресу SRAM..Если...то программа удёт на адрес 0x100 , если добавить ...то на удёт на 0x108, при этом в самой программе меток нет вообще... уважаемый, вы мягко говоря либо не так пишите, либо не так думаете... 1) ОЗУ можно использовать как хошь, в том числе и как хранилище адресов переходов. 2) речь шла немного о других командах,а не рэт. С рэт можно делать более экстравагантные ситуации, где дизасм. сто пудово не пройдёт, даже если будет сечь все регистры и память вместе взятые. 3) Ваш подход не совсем понятен(как пример). Потому, что он путает исходники, а не бинарь как способ уйти от дизасма. Для понимания моей фразы прошу объяснить мне Вашу цитату "метка существует в явном виде". Она существует где??? подумайте хорошенько прежде чем ответить. 4) адресс - это некое число. его можно получить как хотите - хоть сдвигом влево, хоть подсчётом в столбик. способ инициализации адреса в исходниках - феолетово как. главное чтоб при просмотре бинарника это не было понятно. рекомендую найти на просторах инета любые исходники вирусов(для x86 должны быть). и загляните в них. вы так многое узнаете-гарантирую!!! существует приёмы, известные ещё со времён доса, которые использовали профи в вирусах. в своё время, для себя выработал постулат - хочешь научиться писать на азме - напиши вирус(не путать с распространением его). ЗЫ Если интересует конкретика в данном вопросе - ставте задачу, находите способы решения известные вам, выкладывайте на форум. я думаю, что это будет интересно всем - научиться приёмам, которые можно заюзать при решении тех или иных проблем.
|
|
|
|
|
Aug 7 2012, 12:42
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
1. Я не храню там адреса переходов , я использую адреса области SRAM как базовые адреса для перехода к подпрограммам 2. О каких других командах шла речь , если я вообще никакие команды до поста с кодом не приводил. 3. В явном виде , это значит что в памяти программ надо обозначить метку к которой я хочу перейти , что бы компилятор смог вычислить PC-XXXX где XXXX - адрес метки. В любом случае дизас ее покажет. Через SRAM метка не нужна. 4. Да это один из способов адресации к коду в программной памяти. А вопрос был поставлен так Цитата Но вот , что это даёт практически и как это можно использовать не придумаю никак? Т.е. где бы такой выкрутас можно применить? Хорошо , напишу вирус
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
Aug 7 2012, 13:43
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(ILYAUL @ Aug 7 2012, 16:42)  ...2. О каких других командах шла речь...3. В явном виде , это значит что в памяти программ надо обозначить метку к которой я хочу перейти , что бы компилятор смог вычислить PC-XXXX где XXXX - адрес метки. В любом случае дизас ее покажет. Через SRAM метка не нужна.... 2 - простите это я погорячился. действительно icall & ijmp не вы произнесли. 3 - а теперь давайте подумаем как дизазм находит эту метку  найдя явную команду перехода(условного, безусловного, относительного или явного) дизассэмблер рисует метку "XRU_101:" и в ссылках вносит эту метку типа "rjmp XRU_101" в дизассэмблерном коде. т.е. если явно нигде дизасэмблер не найдёт ссылку на данный код - то и метки не будет. т.е. достаточно не создавать таких ссылок. теперь возвращаемся к исходному коду. нахрена себе делать гимор в виде не существующих меток??? вполне достаточно будет имея некий базовый адрес и оффсет до нужного куска кода, чтоб сложить их и получить нужный адресс. это как один из способов получения адреса. (извращатся можно бесконечно кстати) в AVR оффсет команд выравнен на слово. в 86 архитектуре можно было ещё и с этим играться. ик... ЗЫ и это ещё без затрагивания приимуществ AVRов, самопрограммирования, аппаратуры и прочих плюшек в конкретных камнях... ЗЫ ЗЫ И всё же, ышо раз обращаю ваше внимание на то, что указание метки в исходниках не есть причина нахождения метки в дизассэмблере!!! причина в команде ПЕРЕХОДА по данному адресу. А метки сами по себе прятать - то только исходники путать. Отсюда я и спрашивал - задача у вас какая изначально то??? Цитата(ILYAUL @ Aug 7 2012, 16:42)  ...А вопрос был поставлен так ... на вопрос я уже отвечал. там где нужно динамически вычислять адресс перехода. например в "оверлейных" кусках программы. либо всевозможные таблицы переходов - типа аля switch. "конечный автомат" если хотите.
Сообщение отредактировал kolobok0 - Aug 7 2012, 13:44
|
|
|
|
|
Aug 7 2012, 15:34
|

Профессионал
    
Группа: Свой
Сообщений: 1 940
Регистрация: 16-12-07
Из: Москва
Пользователь №: 33 339

|
Спасибо , за пояснения. Цитата Отсюда я и спрашивал - задача у вас какая изначально то??? Если по данному обсуждению то никакой . Я писал программу с ветлениями через ret и допустил ошибку с меткой , забыл вписать метку , да и обозвал ее так же как в .dseg и программа "запрыгала" не туда куда я ожидал. Естественно прояснил почему , ну и дальше Вы уже знаете.
--------------------
Закон Мерфи:
Чем тщательнее составлен проект, тем больше неразбериха, если что-то пошло не так
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|