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

Обсуждаем контроллеры компании Atmel.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Alexeyslav, компактность с точки зрения операций на один обрабатываемый байт. "Обернуть" эту идею в цикл с динамически генерируемой маской большого труда не составит. Могли бы вместо флейма написать это на асме и привести тут - было бы конструктивнее.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Аватара пользователя
zero648
Вымогатель припоя
Сообщения: 650
Зарегистрирован: Пн июн 18, 2012 12:01:04
Откуда: Челябинская область, Копейск

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

Сообщение zero648 »

Моя версия на асме:

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

    ldi    r20, 8
    ldi    r17, 0b01111111
    ldi    r19, 0b10000000
shift:
    ld     r16, X
    mov    r18, r16
    and    r16, r17
    and    r18, r19
    lsl    r18
    or     r16, r18
    st     X+, r16
    clc
    ror    r17
    ror    r19
    dec    r20
    brne   shift
Реклама
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

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

Сообщение Alexeyslav »

R20 можно исключить, он лишний. условие окончания цикла можно отловить по R17. 8-й байт(или первый?) остается без изменения, т.к. 8-й бит у него и так равен нулю, а сдвигать уже собственно и нечего.
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Далеко я от своего компа - проверить не на чем.
По моему способу будет вот как-то так.

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

    ldi    r17, 0b11111111
shift:
    ld     r16, X
    mov    r18, r16
    and    r18, r17
    add    r16, r18
    st     X+, r16
    lsl    r17
    brne   shift
Поправочка: Порядок байт можно изменить начальной установкой X и нужной комбинацией LD/ST -X/X+ .
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Реклама
Эиком - электронные компоненты и радиодетали
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

Спасибо всем откликнувшимся :)
Задача была в сдвиге влево на одну позицию (N-1) информационных бит N-ного байта.
1234567 — просто условное обозначение инф бит. С таким же успехом можно было написать АБВГДЕЁ.
Потому, например, для четвёртого байта из 0АБВГДЕЁ надо получить АБВ0ГДЕЁ.
Поначалу набросал на бумаге вариант с двумя масками (для сдвигаемой и несдвигаемой части байта) и счётчиком.
Но поскольку маски однозначно связаны друг с другом — можно использовать только одну, преобразовывая её.
Ну а мысль про выход из цикла не по счетчику, а по самой маске — круть)

Да, первый байт остаётся без изменений, последний просто целиком сдвигается влево. Но всё равно думаю компактней просто засунуть их всех в цикл не думая.
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Реклама
Аватара пользователя
Jurkin
Вымогатель припоя
Сообщения: 515
Зарегистрирован: Вт янв 01, 2013 15:51:19
Откуда: Vilnius

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

Сообщение Jurkin »

..интересная однако задачка ;)
..немного подумал с учётом универсальной маски- она же счётчик цикла - получилось как то так:

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

    ldi temp1,$FD
    ld temp,X+
    lsl temp
    куда то temp (результат)
  cikl:
    ld temp,X+
lsl temp                         ;был пропущен
    RCALL sdvig_vstavka
    кудо то там temp(результат)
    sec
    rol temp1
    cpi temp1,7F
    brne cikl
    
    
    
  sdvig_vstavka:
      bst temp,1
      bld temp,0
      cpi temp1,$FD
      breq vstavka
      bst temp,2
      bld temp,1
      cpi temp1,$FB
      breq vstavka
      bst temp,3
      bld temp,2
      cpi temp1,$F7
      breq vstavka
      bst temp,4
      bld temp,3
      cpi temp1,$EF
      breq vstavka
      bst temp,5
      bld temp,4
      cpi temp1,$DF
      breq vstavka
      bst temp,6
      bld temp,5
  vstavka:
      and temp,temp1
      ret
..по идее должен работать, тока я беру сначала последнее значение и двигаюсь к первому..
..ну то есть исходные значения в памяти должны распологаться наоборот.

PS ...ошибочку нашёл в своём коде - исправил

PS PS ...ну и проверил в работе(пересчёт перенес из подпрограммы в цикл), получилось(считываю,корректирую,сохраняю(7байт)):
158 тактов, 9.88 мкс при 16Мгц
Последний раз редактировалось Jurkin Сб фев 23, 2013 22:07:43, всего редактировалось 5 раз.
Реклама
Аватара пользователя
Gudd-Head
Друг Кота
Сообщения: 20092
Зарегистрирован: Чт сен 18, 2008 12:27:21
Откуда: Столица Мира Санкт-Петербург

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

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

Jurkin!
После прочтения вашего сообщения я даже не поленился сесть за ноут (по выходным обычно читаюс телефона). Ваш код оскорбил меня тоже имеет право на существование, но только как пример работы с битами.
Вот что по памяти получилось у меня:

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

ldi mask1, 0b00111111; загружаем маску несдвигаемой части байта
ldi mask2, 0b10000000; и сдвигаемой 
ldi counter, 7; и счётчик
loop:; цикл
load data; подгружаем байт
mov tmp, data; копируем его
lsl tmp; сдвигаем влево копию
and data, mask1; маскируем байты
and tmp, mask2; соотв. масками
or data, tmp; и складываем (можно применить add)
save data; сохраняем байт
lsr mask1; модифицируем одну маску нулями,
sec; другую -
ror mask2; единицами
dec counter; дёргаем счётчик
brne loop; проверяем условие выхода из цикла
И это ещё с двумя масками и счётчиком. С одной маской будет как-то так

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

clr mask;
loop:;
...
com mask;
lsr mask;
lsr mask;
and data, mask;
com mask;
lsl mask;
and tmp, mask;
...
brne loop;
[ Всё дело не столько в вашей глупости, сколько в моей гениальности ] [ Правильно заданный вопрос содержит в себе половину ответа ]
Аватара пользователя
Jurkin
Вымогатель припоя
Сообщения: 515
Зарегистрирован: Вт янв 01, 2013 15:51:19
Откуда: Vilnius

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

Сообщение Jurkin »

..ну дык я и не претендую на идеал :) ..может если бы понадобилось ещё компактней, надо былоб ещё чуток помыслить, ну как получилстя, так получился...
..я пчему заинтересовался то ..похож через некоторое время чтот похожее нужно будет себе ваять...
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Добрался до компьютера, проверил.
От первой до второй точки останова 80 тактов.
СпойлерИзображение
Gudd-Head, то что в ОЗУ получилось это то что ты хотел? Или я неправильно понял постановку задачи?
Вложения
zero_n_bit.png
(8.4 КБ) 624 скачивания
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

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

Сообщение afz »

А как принято делать двухбайтовые счетчики? Вот мне понадобилось в таймерном прерывании 2400 Гц отсчитать секунду. Я, как на нормальных системах, загрузил в пару регистров 2400 (hi , low), но что-то мне подсказало заглянуть в описание команды DEC. Ага, так и ждал подляны: DEC не взводит бит C. Ну и как прикажете считать? Нет, конечно, мне не составило труда посчитать в одном регистре 100 и во втором 24, но это удобный частный случай, а понадобись посчитать простое число, не влезающее в один регистр, хотя бы 2437 и как тогда принято делать?
Последний раз редактировалось afz Вс фев 24, 2013 13:54:17, всего редактировалось 1 раз.
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Речь об AVR, судя по "симптомам". :)
Смотрите SUB, SUBI, SBIW

Добавил несколько минут спустя: посмотри ещё макросы от Чана http://radiokot.ru/forum/viewtopic.php? ... 4#p1575104
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

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

Сообщение afz »

Kavka писал(а):Речь об AVR, судя по "симптомам". :)
Екстественно - тема-то "Ассемблер AVR"
Kavka писал(а): Смотрите SUB, SUBI, SBIW
Да-да, и еще два регистра под константу 0х001. В прерывании. И еще пара команд, чтобы занести эту константу в регистры. По сравнению с
dec r1
sbc r0
в нормальных системах. Особенно интересна команда SBIW, которая работает только с R24-R31. Блин, ну до чего корявая и дилетантская система команд. 32 общих регистра, да. Нагло врут! ОБЩИХ (действительно общих) регистров всего 6 - R26-R31. Почти общих - еще 2: добавляются R24, R25, с остальными не работают команды ADIW/SBIW. Более-менее общих - еще 8: R16-R23. С остальными R0-R15 не работает половина команд. Бить лицо. Ногами.

Нет, учитывая то, что флаг V команда DEC таки взводит, можно подобрать набор констатн, который поможет справиться несколькими командами, по типу
...
DEC r16
brvc L1
ldi r16,Con1
dec r17
brvc L1
ldi r17,Con2
L1:or R16,R17
breq SecOK
...
Вот и интересуюсь: нет ли проверенных решений?
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

А в сторону TST не смотрели перед вычитанием?
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

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

Сообщение afz »

Kavka писал(а):А в сторону TST не смотрели перед вычитанием?
Нет, я же воспользовался частным случаем: 2400 = 24 * 100, свою задачу я решил. А вот что делать, допустим, с 2399 или 2411, которые суть простые числа, то есть не делятся ни на что, кроме себя самого и единицы? Так сказать, на будущее...
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
akl
Друг Кота
Сообщения: 4444
Зарегистрирован: Пт мар 07, 2008 06:54:43
Откуда: Ижевск

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

Сообщение akl »

afz писал(а):
Спойлер

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

    DEC   r16
    brvc   L1
    ldi      r16,Con1
    dec    r17
    brvc   L1
    ldi      r17,Con2
L1:or      R16,R17
    breq   SecOK
...
Вот и интересуюсь: нет ли проверенных решений?
afz писал(а):А вот что делать, допустим, с 2399 или 2411

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

     LDI   XH,HIGH(2399)   ; с таким же успехом загружается любое другое число в пределах 1...65535
     LDI   XL,LOW(2399)   ; R25:R24, YL:YH, ZL:ZH
;
;
;
     SBIW   XH:XL,1
     BRNE   OUT
; установить признак окончания 1 секунды
OUT:
     RETI
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

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

Сообщение Alexeyslav »

Флаг N анализировать при декременте и флаг Z при инкременте. условным оператором производить декремент старшего байта, если флаг N стоит, всего на один/два такта больше и одну команду в исходнике.

R0 - младший байт пары, R1 - старший.

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

 DEC R0
 BRPL PC+1   ; если результат положительный - пропускаем следующую команду. Результат будет неположительный при попытке декремента нуля.
 DEC R1
Мжно прикрутить и SBIS/SBIC но они дольше выполняются поскольку обращение идет к портам ввода-вывода.
Последний раз редактировалось Alexeyslav Вс фев 24, 2013 16:37:39, всего редактировалось 1 раз.
Аватара пользователя
afz
Опытный кот
Сообщения: 744
Зарегистрирован: Сб дек 22, 2012 08:17:42
Откуда: Караганда, Казахстан

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

Сообщение afz »

akl
Спасибо, это я знаю и так. А теперь, пожалуйста, то же самое для (R0, R1).
X-Y-Z заняты. И R24-R25 трогать нельзя. То есть, конечно, можно сохранить их, а потом восстановить, но меня интересует именно прямой вариант вычислений в (R0, R1).

Alexeyslav
Это будет счет по модулю 128, а не 256. Нет, тут надо напрячься и сообразить формулу пересчета, как из простого двоичного двухбайтового числа получить два байта, только с переносом при переходе не через 0х00 - 0хFF, а через 0x80 - 0x7F Это что, к каждому байту надо добавить 0x80? Блин, не выспался сегодня, не соображу сразу...
Кто мешает тебе выдумать порох непромокаемый? (К. Прутков, мысль № 133)
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Что-то вот такое...
R1:R0 - старший:младший

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

    tst r0
    brne  L1
    dec r1
L1:
    dec r0
дальше cpi с нулями.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Alexeyslav
Друг Кота
Сообщения: 4550
Зарегистрирован: Чт май 05, 2011 21:26:34
Откуда: Украина, Славутич
Контактная информация:

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

Сообщение Alexeyslav »

Получается еще хуже, надо будет тогда дополнительно R0 обнулять. Но выходит простой декремент для чисел укладывающихся в 15 бит. просто надо 7-й бит младшего разряда сдвинуть в 0-й бит старшего. Проще проверить на ноль до декремента, и если ноль - то декремент R1 а потом только безусловный декремент R0.

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

TST R0
BRNE PC+1
DEC R1
DEC R0
Все-таки я думал что N появляется когда вычитаешь из числа большее, а оно оказывается просто 7-й бит туда берет. Ну подумаешь... получилось не тремя так 4-мя командами.

п.с. не встиг как говорится :kill:
Аватара пользователя
Kavka
Мудрый кот
Сообщения: 1810
Зарегистрирован: Чт июн 10, 2010 08:55:35
Откуда: Сибирские Афины

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

Сообщение Kavka »

Ничего обнулять не надо.
TST – Test for Zero or Minus
Tests if a register is zero or negative. Performs a logical AND between a register and itself.
Когда уже ничего не помогает - прочтите, наконец, инструкцию.
Лучший оптимизатор находится у вас между ушей. (Майкл Абраш, программист Quake и QuakeII)
Избыток информации ведёт к оскудению души - Леонтьев А. (сказано в 1965 г.)
Ответить

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