|
Перестановка бит в байте, получить зеркальное отображение |
|
|
2 страниц
1 2 >
|
 |
Ответов
(1 - 21)
|
Nov 6 2008, 11:39
|
Местный
  
Группа: Участник
Сообщений: 246
Регистрация: 4-12-06
Пользователь №: 23 101

|
Цитата(bbill @ Nov 6 2008, 14:28)  Появилась необходимость (из-за разводки) перевернуть байт: было 0b76543210 стало 0b01234567
Можно тупо bld/bst, но хотелось бы покороче. Кто сталкивался с подобной задачей.
P.S. В поиске нашел только обсуждение о перестановке двух бит. Код ; 13 words / 13 cycles ; tmp= abcdefgh mov tmp2,tmp; tmp2= abcdefgh andi tmp2,0b01010101; tmp2= 0b0d0f0h andi tmp, 0b10101010; tmp= a0c0e0g0 bst tmp2,0; T=h lsr tmp2 ; tmp2= 00b0d0f0 bld tmp2,7; tmp2= h0b0d0f0 lsl tmp ; tmp= 0c0e0g00 C=a adc tmp, tmp2; tmp= hcbedgfa mov tmp2,tmp; tmp2= hcbedgfa andi tmp2,0b01100110; tmp2= 0cb00gf0 swap tmp2 ; tmp2= 0gf00cb0 andi tmp, 0b10011001; tmp= h00ed00a add tmp, tmp2; tmp= hgfedcba так длинно? тогда в сад в порт
Сообщение отредактировал Maik-vs - Nov 6 2008, 11:42
|
|
|
|
|
Nov 6 2008, 11:50
|
Группа: Новичок
Сообщений: 9
Регистрация: 15-02-08
Пользователь №: 35 076

|
Цитата(bbill @ Nov 6 2008, 16:28)  Появилась необходимость (из-за разводки) перевернуть байт: было 0b76543210 стало 0b01234567
Можно тупо bld/bst, но хотелось бы покороче. Кто сталкивался с подобной задачей.
P.S. В поиске нашел только обсуждение о перестановке двух бит. Я когда такое делал, особо не задумывался, про bld/bst не знал, да и задачи экономии ресурсов не стояло. Поэтому получилась такая программа на C. (листинг после компиляции в WinAVR) Код static const uint8_t REVERT_NIBBLE[] = { 0x0, 0x8, 0x4, 0xc, 0x2, 0xa, 0x6, 0xe, 0x1, 0x9, 0x5, 0xd, 0x3, 0xb, 0x7, 0xf };
uint8_t Revert_Byte(uint8_t Data) { 4ea: 98 2f mov r25, r24 4ec: 92 95 swap r25 4ee: 9f 70 andi r25, 0x0F; 15 4f0: ed e4 ldi r30, 0x4D; 77 4f2: f1 e0 ldi r31, 0x01; 1 4f4: df 01 movw r26, r30 4f6: a9 0f add r26, r25 4f8: b1 1d adc r27, r1 4fa: 8f 70 andi r24, 0x0F; 15 4fc: e8 0f add r30, r24 4fe: f1 1d adc r31, r1 500: 80 81 ld r24, Z 502: 82 95 swap r24 504: 80 7f andi r24, 0xF0; 240 506: 9c 91 ld r25, X 508: 89 2b or r24, r25 return((REVERT_NIBBLE[Data >> 4]) | ((REVERT_NIBBLE[Data & 0x0F] << 4))); } 50a: 99 27 eor r25, r25 50c: 08 95 ret IMHO на асме с bld/bst будет и короче и быстрее
|
|
|
|
|
Nov 6 2008, 12:45
|

Участник

Группа: Свой
Сообщений: 63
Регистрация: 13-03-06
Из: Москва
Пользователь №: 15 204

|
Цитата(bbill @ Nov 6 2008, 15:28)  Можно тупо bld/bst, но хотелось бы покороче. Кто сталкивался с подобной задачей. Код ldi cntreg,8 l1: rol tmp ror tmp2 dec cntreg brne l1 Покороче, но оч медленно. На выходе в tmp2 имеем перевертыш. Ну и регистры почем зря используем. :-)
|
|
|
|
|
Nov 6 2008, 14:32
|
Местный
  
Группа: Свой
Сообщений: 303
Регистрация: 3-03-05
Пользователь №: 3 044

|
Цитата(bbill @ Nov 6 2008, 14:28)  Появилась необходимость (из-за разводки) перевернуть байт: было 0b76543210 стало 0b01234567 А если подумать и посчитать? Код ;============================================== ;РАЗВОРОТ БАЙТА 7-0 в 0-7 ;stable - время выполнения не зависит от данных
;--------------------------------------------------------------- ; 16 words 18 clk stable (минус rjmp или ret)
M31: bst rTmp,0 bld rTmpH,7
bst rTmp,1 bld rTmpH,6
bst rTmp,2 bld rTmpH,5
bst rTmp,3 bld rTmpH,4
bst rTmp,4 bld rTmpH,3
bst rTmp,5 bld rTmpH,2
bst rTmp,6 bld rTmpH,1
bst rTmp,7 bld rTmpH,0 rjmp M31
;------------------------------------------------------------- ; 5 words 42 clk stable (минус rjmp или ret) M21: ldi rCnt,8 l1: rol rTmp ror rTmpH dec rCnt brne l1 rjmp M21
;-------------------------------------------------------------- ; 4 word's 32 clk stable ldi rTmpH,1 M1: lsr rTmp rol rTmpH brcc M1 Выбирайте, что дороже: код, время и стабильность времени выполнения или время копирования одинаковых строк кода в редакторе. AVR Studio легко позволяет почти все проверить и измерить, если не лениться.
--------------------
Опыт - чудесная вещь: легко использовать, можно продать, трудно пропить.
|
|
|
|
|
Nov 6 2008, 14:46
|
Частый гость
 
Группа: Участник
Сообщений: 76
Регистрация: 21-10-05
Пользователь №: 9 941

|
Спасибо Maik-vs. И короче, и главное быстрее. А еще короче можешь Всем остальным спасибо за участие. P.S. Что bld/bst, что ror/rol, та же пара регистров и те же 16 тактов. Циклы не считаем. Мне в данном случае важнее скорость.
|
|
|
|
|
Nov 7 2008, 21:39
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(ARV @ Nov 7 2008, 18:45)  вот на телесистемах была пару раз ветка по этой теме (поиск рулит) - там просто перлы были! 11 тактов, кажется или даже меньше! НЕ ВЕРЮ! Покажите <13 на AVR... на PIC можно за 12
|
|
|
|
|
Nov 8 2008, 05:27
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(singlskv @ Nov 8 2008, 00:39)  на PIC можно за 12 Под "PIC" подразумевается 16-ая или 18-ая серии? Тогда интересно было бы взглянуть на реверс из трех инструкций... А для АВР можно и меньше 10 тактов если использовать таблицу.
|
|
|
|
|
Nov 8 2008, 10:43
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(singlskv @ Nov 8 2008, 06:39)  НЕ ВЕРЮ! Покажите <13 на AVR...
на PIC можно за 12 12 тактовКод Reverse_1:; реверс бит в байте (R4 - вход/выход)
; обмен средних бит в тетрадах mov R17,R4 andi R17,0b10011001 sub R4,R17 swap R4 or R4,R17 ; выделение четных/нечетных бит mov R17,R4 andi R17,0b10101010 sub R4,R17 ; обмен четных/нечетных бит out SREG,R4 ror R4 lsl R17 adc R4,R17
Порядок преобразования: a b c d e f g h C a f g d e b c h 0 a - g - e - c - 0 - f - d - b - h 0 h - f - d - b - - - g - e - c - - a h g f e d c b a 0
Единственный тонкий момент: обнуление I (запрет прерываний) С разбегу обойти его мне не удалось без добавления 13-го такта.
©argus98 - все права защищены :))
|
|
|
|
|
Nov 8 2008, 20:22
|
дятел
    
Группа: Свой
Сообщений: 1 681
Регистрация: 13-05-06
Из: Питер
Пользователь №: 17 065

|
Цитата(ae_ @ Nov 8 2008, 13:43)  12 тактовКод Reverse_1:; реверс бит в байте (R4 - вход/выход)
; обмен средних бит в тетрадах mov R17,R4 andi R17,0b10011001 sub R4,R17 swap R4 or R4,R17 ; выделение четных/нечетных бит mov R17,R4 andi R17,0b10101010 sub R4,R17 ; обмен четных/нечетных бит out SREG,R4 ror R4 lsl R17 adc R4,R17
Порядок преобразования: a b c d e f g h C a f g d e b c h 0 a - g - e - c - 0 - f - d - b - h 0 h - f - d - b - - - g - e - c - - a h g f e d c b a 0
Единственный тонкий момент: обнуление I (запрет прерываний) С разбегу обойти его мне не удалось без добавления 13-го такта. Ну это не до конца честный вариант, Код out SREG,R4 ror R4 нужно менять на Код bst R4,0 lsr R4 bld R4,7 а это уже 13 тактов... Кстати говоря, тк тема снова всплыла, есть небольшая модификация 13тактового алгоритма которая позволяет отказаться от использования бита T в SREG: Код ; 13 words / 13 cycles ; ;tmp= abcdefgh mov tmp2, tmp ;tmp2= abcdefgh asr tmp ;tmp= aabcdefg C=h ror tmp2 ;tmp2= habcdefg C=h rol tmp ;tmp= abcdefgh C=a rol tmp ;tmp= bcdefgha andi tmp2, 0b10101010 ;tmp2= h0b0d0f0 andi tmp, 0b01010101 ;tmp= 0c0e0g0a add tmp, tmp2 ;tmp= hcbedgfa mov tmp2, tmp ;tmp2= hcbedgfa andi tmp2, 0b01100110 ;tmp2= 0cb00gf0 swap tmp2 ;tmp2= 0gf00cb0 andi tmp, 0b10011001 ;tmp= h00ed00a add tmp, tmp2 ;tmp= hgfedcba но увы все равно 13...  Цитата(Qwertty @ Nov 8 2008, 08:27)  Под "PIC" подразумевается 16-ая или 18-ая серии? Тогда интересно было бы взглянуть на реверс из трех инструкций... Увы, для PIC сейчас найти не могу, а писать заново не буду, Пики я только "со словарем", потаму как редко... Насколько я помню, пойдет даже на 10/12 серии..., экономия 1 такта там из-за аккамуляторной модели, типа можно сделать сдвиг и получить в результате 2 числа одно сдвинутое а второе исходное... как то так...
|
|
|
|
|
Nov 8 2008, 22:42
|
Местный
  
Группа: Свой
Сообщений: 408
Регистрация: 21-10-06
Из: Санкт-Петербург
Пользователь №: 21 527

|
Цитата(singlskv @ Nov 8 2008, 23:22)  Увы, для PIC сейчас найти не могу, а писать заново не буду, Пики я только "со словарем", потаму как редко... Насколько я помню, пойдет даже на 10/12 серии..., экономия 1 такта там из-за аккамуляторной модели, типа можно сделать сдвиг и получить в результате 2 числа одно сдвинутое а второе исходное... как то так... Идет даже на 10/12 серии!!! Напряжение нарастает  За 12 тактов 10/12/16/18 серии выполняют ТРИ коротких инструкции или 1,5 длинных. Как в это упаковать реверс 8 бит я не понимаю.
|
|
|
|
|
Nov 9 2008, 00:47
|
Участник
  
Группа: Свой
Сообщений: 462
Регистрация: 2-04-07
Из: Иркутск
Пользователь №: 26 695

|
Цитата(Qwertty @ Nov 9 2008, 07:42)  Идет даже на 10/12 серии!!! Напряжение нарастает :) За 12 тактов 10/12/16/18 серии выполняют ТРИ коротких инструкции или 1,5 длинных. Как в это упаковать реверс 8 бит я не понимаю. Для PIC "такты" нужно заменить на "МЦ", для AVR тоже можно заменить, но т.к. для AVR они совпадают, то "такт" часто используется вместо "МЦ".
Сообщение отредактировал ae_ - Nov 9 2008, 00:50
|
|
|
|
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|