Страница 178 из 400

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

Добавлено: Сб фев 23, 2013 12:55:52
Kavka
Alexeyslav, компактность с точки зрения операций на один обрабатываемый байт. "Обернуть" эту идею в цикл с динамически генерируемой маской большого труда не составит. Могли бы вместо флейма написать это на асме и привести тут - было бы конструктивнее.

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

Добавлено: Сб фев 23, 2013 13:58:48
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

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

Добавлено: Сб фев 23, 2013 14:36:12
Alexeyslav
R20 можно исключить, он лишний. условие окончания цикла можно отловить по R17. 8-й байт(или первый?) остается без изменения, т.к. 8-й бит у него и так равен нулю, а сдвигать уже собственно и нечего.

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

Добавлено: Сб фев 23, 2013 14:57:44
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+ .

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

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

Да, первый байт остаётся без изменений, последний просто целиком сдвигается влево. Но всё равно думаю компактней просто засунуть их всех в цикл не думая.

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

Добавлено: Сб фев 23, 2013 17:26:53
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Мгц

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

Добавлено: Сб фев 23, 2013 17:48:13
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;

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

Добавлено: Сб фев 23, 2013 17:58:15
Jurkin
..ну дык я и не претендую на идеал :) ..может если бы понадобилось ещё компактней, надо былоб ещё чуток помыслить, ну как получилстя, так получился...
..я пчему заинтересовался то ..похож через некоторое время чтот похожее нужно будет себе ваять...

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

Добавлено: Сб фев 23, 2013 18:47:34
Kavka
Добрался до компьютера, проверил.
От первой до второй точки останова 80 тактов.
СпойлерИзображение
Gudd-Head, то что в ОЗУ получилось это то что ты хотел? Или я неправильно понял постановку задачи?

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

Добавлено: Вс фев 24, 2013 13:37:22
afz
А как принято делать двухбайтовые счетчики? Вот мне понадобилось в таймерном прерывании 2400 Гц отсчитать секунду. Я, как на нормальных системах, загрузил в пару регистров 2400 (hi , low), но что-то мне подсказало заглянуть в описание команды DEC. Ага, так и ждал подляны: DEC не взводит бит C. Ну и как прикажете считать? Нет, конечно, мне не составило труда посчитать в одном регистре 100 и во втором 24, но это удобный частный случай, а понадобись посчитать простое число, не влезающее в один регистр, хотя бы 2437 и как тогда принято делать?

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

Добавлено: Вс фев 24, 2013 13:47:28
Kavka
Речь об AVR, судя по "симптомам". :)
Смотрите SUB, SUBI, SBIW

Добавил несколько минут спустя: посмотри ещё макросы от Чана http://radiokot.ru/forum/viewtopic.php? ... 4#p1575104

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

Добавлено: Вс фев 24, 2013 14:20:45
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
...
Вот и интересуюсь: нет ли проверенных решений?

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

Добавлено: Вс фев 24, 2013 14:31:17
Kavka
А в сторону TST не смотрели перед вычитанием?

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

Добавлено: Вс фев 24, 2013 14:38:14
afz
Kavka писал(а):А в сторону TST не смотрели перед вычитанием?
Нет, я же воспользовался частным случаем: 2400 = 24 * 100, свою задачу я решил. А вот что делать, допустим, с 2399 или 2411, которые суть простые числа, то есть не делятся ни на что, кроме себя самого и единицы? Так сказать, на будущее...

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

Добавлено: Вс фев 24, 2013 16:15:15
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

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

Добавлено: Вс фев 24, 2013 16:34:52
Alexeyslav
Флаг N анализировать при декременте и флаг Z при инкременте. условным оператором производить декремент старшего байта, если флаг N стоит, всего на один/два такта больше и одну команду в исходнике.

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

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

 DEC R0
 BRPL PC+1   ; если результат положительный - пропускаем следующую команду. Результат будет неположительный при попытке декремента нуля.
 DEC R1
Мжно прикрутить и SBIS/SBIC но они дольше выполняются поскольку обращение идет к портам ввода-вывода.

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

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

Alexeyslav
Это будет счет по модулю 128, а не 256. Нет, тут надо напрячься и сообразить формулу пересчета, как из простого двоичного двухбайтового числа получить два байта, только с переносом при переходе не через 0х00 - 0хFF, а через 0x80 - 0x7F Это что, к каждому байту надо добавить 0x80? Блин, не выспался сегодня, не соображу сразу...

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

Добавлено: Вс фев 24, 2013 17:00:25
Kavka
Что-то вот такое...
R1:R0 - старший:младший

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

    tst r0
    brne  L1
    dec r1
L1:
    dec r0
дальше cpi с нулями.

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

Добавлено: Вс фев 24, 2013 17:06:29
Alexeyslav
Получается еще хуже, надо будет тогда дополнительно R0 обнулять. Но выходит простой декремент для чисел укладывающихся в 15 бит. просто надо 7-й бит младшего разряда сдвинуть в 0-й бит старшего. Проще проверить на ноль до декремента, и если ноль - то декремент R1 а потом только безусловный декремент R0.

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

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

п.с. не встиг как говорится :kill:

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

Добавлено: Вс фев 24, 2013 17:10:34
Kavka
Ничего обнулять не надо.
TST – Test for Zero or Minus
Tests if a register is zero or negative. Performs a logical AND between a register and itself.