|
|
  |
Ассемблер AVR |
|
|
|
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 — оператор языка, в препроцессоре он не должен работать.
--------------------
Ну, я пошёл… Если что – звоните…
|
|
|
|
|
  |
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|