Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: зеркальное отражение битового массива  (Прочитано 21579 раз)
0 Пользователей и 1 Гость смотрят эту тему.
S
Гость
« : 10-05-2007 20:19 » 

столкнулся с необходимостью написания проги для зеркального отражения битового массива (64х64)?
пытаюсь написать прогу на TASM. напрямую с битами работать неполучается, значит нужно работать через xor и and? как проще реализовать этот алгоритм?
Записан
Scorp__)
Молодой специалист

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 10-05-2007 20:41 » 

S, зеркального отражения это как?

Если массив из двух байт 0000 1111 1111 0000
То как будет выглядеть его отражение не изменится или 1111 0000 0000 1111

То есть отражаются только байты или вся строчка целиком? И массив 64х64 это 64 четверных слова? И каждая строчка отражается отдельно?
Записан

- А Вы сами-то верите в привидения?
- Конечно, нет, - ответил лектор и медленно растаял в воздухе.
S
Гость
« Ответ #2 : 10-05-2007 21:17 » 

Scorp__), 64х64 бита ну т.е. 64 строки по 8 байт
в твоем примере массив после отражения не изменится,
отражается вся строка
каждая строка масива должна быть зеркально отражена
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 11-05-2007 05:10 » 

S,

спецкоманд для этого нету, всё ручками )
в общем случае, без привязки к чётности длины строчки байт:

1) берёшь очередную строку из 8 байт
2) заводишь счётчики - A и B , один сначала, другой с конца
{
  3) определяешь для A номер быйта и маску бита
  4) определяешь для B номер быйта и маску бита
  5) переставляешь биты местами
  6) сдвигаешь "указатель" к центру строки (с контролем "границы" - центра)
  7) повторяем с 3)
}

8 ) повторяем с 1)
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #4 : 11-05-2007 06:19 » 

можно поиграться сдвигами
копируешь искомое в сдвиговое
сдвигаешь влево, бит переноса
сдвигаешь вправо с битом переноса

получаешь зеркальное отображение
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 11-05-2007 06:28 » 

ИМХО такие вещи быстрее и проще делать через масочное копирование )
хотя, дело вкуса

а, нет, гоню ... для асма удобнее сдвигом всё же
« Последнее редактирование: 11-05-2007 06:31 от Алексей1153++ » Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #6 : 11-05-2007 06:40 » 

а можно даже очень быстро Улыбаюсь
делаешь заранее массив (256) уже зеркально отраженных
а потом, просто пробегая по искомому массиву вытягивать из подготовленного по индексу.
быстро, очень быстро (память? ну, плюс-минус 256 байт в коде Улыбаюсь
а в предыдущем предложении - это ж скока сдвигов.
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #7 : 11-05-2007 07:07 » 

Sla,
дык
>>делаешь заранее массив (256) уже зеркально отраженных
 - это точно столько же сдвигов ))
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #8 : 11-05-2007 07:36 » 

Алексей1153++, ты наверное не понял Улыбаюсь
типа

db 0,010000000b,001000000b,011000000b,....
т.е ЗАРАНЕЕ подготовили
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #9 : 11-05-2007 08:20 » 

Sla, это же не подойдёт...

или я правда твою мысль не поднял ) 

ааа, терь понял , таблица всех перевёрнутых....  Это быстро )

но некрасиииво )

То есть это для случая, когда нужна скорость. Но тогда можно эту таблицу создать динамически перед кучей отзеркаливаний, а не объявлять статически. Тохда всё снова красиво )
« Последнее редактирование: 11-05-2007 08:24 от Алексей1153++ » Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #10 : 11-05-2007 12:18 » 

Код: (ASM)
    mov esi, offset array
    mov ecx, 64
L0:
    mov eax, [esi + 0]
    mov edx, [esi + 4]
    mov bl, 8
L1:
    rol eax
    ror edx
    dec bl
    jnz L1
    rol eax
    mov [esi + 0], edx
    mox [esi + 4], eax
    add esi, 8
    loop L0

Насчет команд ROR и ROL - стоит уточнить - я уже порядком подзабыл.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #11 : 11-05-2007 13:29 » 

RXL, решил размяться?
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #12 : 11-05-2007 14:27 » 

Ром, чёт не работает...

а я решил в студии прокатать код (больше негде), у меня получилось вот чего )
(проверено, работает)

Код:
#define asize 64 //размер массива ( кратно 8)
#define division 8//размер регистров eax, eвx
static BYTE array[asize]=
{0xff,0,0,0,0xff,0,0,0xf0};

BYTE* by=array;
DWORD dwdrig,dwdlef;
_asm
{
mov esi, offset array
mov ecx, asize/division
L0:
mov eax, [esi + 0]
mov edx, [esi + 4]
mov bl, 64
mov dwdrig,0
mov dwdlef,0
L1:
ror dwdrig,1
rol eax,1
jnc L1_1
or dwdrig,80000000h
L1_1:
rol dwdlef,1
ror edx,1
jnc L1_2
or dwdlef,1
L1_2:
dec bl
jnz L1

mov edx,dwdlef
mov [esi + 0], edx
mov edx,dwdrig
mov [esi + 4], edx
add esi, 8
loop L0
};
« Последнее редактирование: 11-05-2007 14:30 от Алексей1153++ » Записан

RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #13 : 11-05-2007 15:06 » 

Sla, типа того - типа рабочий день еще не совсем кончился, а уже хочется не работать Ага

Алексей1153++, у меня там минимум одна ошибка: mov bl, 32

ROR и ROL надо заменить на RCR и RCL.

« Последнее редактирование: 11-05-2007 16:05 от RXL » Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #14 : 11-05-2007 15:09 » 

просто без прогона кода косяки всегда бывают ) Это на 99,99% верно всегда

ROR и ROL тоже катят, кстати
Записан

Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #15 : 11-05-2007 15:21 » 

мне вот че подумалось, да тута, или тама? можно один цикл убрать Улыбаюсь
надо делать так

сдвинул влево
задвинул вправо
сдвинул влево
задвинул вправо
и так 8 раз

быстрее должно получится, чем в цикле Улыбаюсь
Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
Sla
Команда клуба

ua
Offline Offline
Пол: Мужской

WWW
« Ответ #16 : 11-05-2007 15:35 » 

Цитата
просто без прогона кода косяки всегда бывают ) Это на 99,99% верно всегда
Эх, молодежь.... Персональный компьютер....
1 комп = 1 программист.

а ведь были времена....
1 комп = N программист / машинное время
и.... полная компиляция проекта 2,5 часа + прошивка ПЗУ + не дай бог, ошибка - стереть ПЗУ  ---- > начинай сначала

Что-то автор потерялся
« Последнее редактирование: 11-05-2007 21:11 от Джон » Записан

Мы все учились понемногу... Чему-нибудь и как-нибудь.
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #17 : 11-05-2007 16:11 » 

Алексей1153++, нет, не катят. ROR и ROL - циклический сдвиг внутри регистра, а RCL и RCR - циклический сдвиг регистра через CF.

Студии под рукой нет, т.ч. накидал для GCC...

t1.c:
Код: (C)
#include <stdio.h>

void mirror_h(unsigned char * array);
void print_array(unsigned char * array);

int main()
{
    unsigned char array[512];
    int i;

    for (i = 0; i < 512; i++)
        array[i] = i;

    print_array(array);

    mirror_h(array);

    print_array(array);

    return 0;
}

void print_array(unsigned char * array)
{
    int i, l = 0;
    char * s = (char*)malloc(6000);

    for (i = 0; i < 512; i++)
    {
        if (i && !(i&7))
            s[l - 1] = '\n';

        l += sprintf(&s[l], "%u%u%u%u%u%u%u%u ",
            array[i] & 1,
            (array[i] >> 1) & 1,
            (array[i] >> 2) & 1,
            (array[i] >> 3) & 1,
            (array[i] >> 4) & 1,
            (array[i] >> 5) & 1,
            (array[i] >> 6) & 1,
            (array[i] >> 7) & 1
        );
    }

    s[l - 1] = 0;

    puts("-------------------");
    puts(s);
    puts("-------------------");
}

t2.S:
Код: (ASM)
/*
    void mirror_h(unsigned char * array)
*/

.text
.align 4
.globl mirror_h
mirror_h:
        movl 4(%esp), %esi
        movl $64, %ecx

L0:
        movl 0(%esi), %eax
        movl 4(%esi), %edx
        movb $32, %bl

L1:
        rcll %eax
        rcrl %edx
        decb %bl
        jnz L1

        rcll %eax

        movl %eax, 0(%esi)
        movl %edx, 4(%esi)

        addl $8, %esi
        loop L0

        ret

сборка:
# gcc -o t1 -g t1.c t2.S

Результат поход на правду.
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #18 : 11-05-2007 16:56 » 

RXL, ror и rol во флаг переноса тоже засовывают. А иначе мой вариант бы не заработал

Sla, а вот реализация твоего решения с таблицей инверсных чисел )

Код:
#define iB(by) (\
((by&0x01)<<7) |\
((by&0x02)<<5) |\
((by&0x04)<<3) |\
((by&0x08)<<1) |\
((by&0x10)>>1) |\
((by&0x20)>>3) |\
((by&0x40)>>5) |\
((by&0x80)>>7))

#define invert_size 256
static BYTE invert[invert_size]=
{
iB(0  ),iB(1  ),iB(2  ),iB(3  ),iB(4  ),iB(5  ),iB(6  ),iB(7  ),
iB(8  ),iB(9  ),iB(10 ),iB(11 ),iB(12 ),iB(13 ),iB(14 ),iB(15 ),
iB(16 ),iB(17 ),iB(18 ),iB(19 ),iB(20 ),iB(21 ),iB(22 ),iB(23 ),
iB(24 ),iB(25 ),iB(26 ),iB(27 ),iB(28 ),iB(29 ),iB(30 ),iB(31 ),
iB(32 ),iB(33 ),iB(34 ),iB(35 ),iB(36 ),iB(37 ),iB(38 ),iB(39 ),
iB(40 ),iB(41 ),iB(42 ),iB(43 ),iB(44 ),iB(45 ),iB(46 ),iB(47 ),
iB(48 ),iB(49 ),iB(50 ),iB(51 ),iB(52 ),iB(53 ),iB(54 ),iB(55 ),
iB(56 ),iB(57 ),iB(58 ),iB(59 ),iB(60 ),iB(61 ),iB(62 ),iB(63 ),
iB(64 ),iB(65 ),iB(66 ),iB(67 ),iB(68 ),iB(69 ),iB(70 ),iB(71 ),
iB(72 ),iB(73 ),iB(74 ),iB(75 ),iB(76 ),iB(77 ),iB(78 ),iB(79 ),
iB(80 ),iB(81 ),iB(82 ),iB(83 ),iB(84 ),iB(85 ),iB(86 ),iB(87 ),
iB(88 ),iB(89 ),iB(90 ),iB(91 ),iB(92 ),iB(93 ),iB(94 ),iB(95 ),
iB(96 ),iB(97 ),iB(98 ),iB(99 ),iB(100),iB(101),iB(102),iB(103),
iB(104),iB(105),iB(106),iB(107),iB(108),iB(109),iB(110),iB(111),
iB(112),iB(113),iB(114),iB(115),iB(116),iB(117),iB(118),iB(119),
iB(120),iB(121),iB(122),iB(123),iB(124),iB(125),iB(126),iB(127),
iB(128),iB(129),iB(130),iB(131),iB(132),iB(133),iB(134),iB(135),
iB(136),iB(137),iB(138),iB(139),iB(140),iB(141),iB(142),iB(143),
iB(144),iB(145),iB(146),iB(147),iB(148),iB(149),iB(150),iB(151),
iB(152),iB(153),iB(154),iB(155),iB(156),iB(157),iB(158),iB(159),
iB(160),iB(161),iB(162),iB(163),iB(164),iB(165),iB(166),iB(167),
iB(168),iB(169),iB(170),iB(171),iB(172),iB(173),iB(174),iB(175),
iB(176),iB(177),iB(178),iB(179),iB(180),iB(181),iB(182),iB(183),
iB(184),iB(185),iB(186),iB(187),iB(188),iB(189),iB(190),iB(191),
iB(192),iB(193),iB(194),iB(195),iB(196),iB(197),iB(198),iB(199),
iB(200),iB(201),iB(202),iB(203),iB(204),iB(205),iB(206),iB(207),
iB(208),iB(209),iB(210),iB(211),iB(212),iB(213),iB(214),iB(215),
iB(216),iB(217),iB(218),iB(219),iB(220),iB(221),iB(222),iB(223),
iB(224),iB(225),iB(226),iB(227),iB(228),iB(229),iB(230),iB(231),
iB(232),iB(233),iB(234),iB(235),iB(236),iB(237),iB(238),iB(239),
iB(240),iB(241),iB(242),iB(243),iB(244),iB(245),iB(246),iB(247),
iB(248),iB(249),iB(250),iB(251),iB(252),iB(253),iB(254),iB(255)
};


#define asize 8
static BYTE array_to_invert[asize]={0xff,0,0,0,0xff,0,0,0xf0};

// BYTE* by=array_to_invert;

_asm
{
mov edi, offset invert
mov esi, offset array_to_invert
mov ebx, 0 ;индекс в array_to_invert , идём с начала
mov ecx, asize/2 ;индекс в array_to_invert , идём с конца

mov eax,0
mov edx,0

L0:
mov al, byte ptr [esi+ebx] ;берём очередной байт
mov dl, byte ptr [esi+ecx+asize/2-1] ;

mov al, byte ptr [edi+eax] ;инверсия байта
mov dl, byte ptr [edi+edx] ;

mov byte ptr [esi+ebx], dl ;кладём взад (перекрёстно)
mov byte ptr [esi+ecx+asize/2-1], al ;

inc ebx
loop L0 ;dec ecx
};
Записан

Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #19 : 11-05-2007 17:09 » 

а, блин, я не то сделал. Я сделал сразу для всего массива, а надо то по 8 байт )))

придёца ещё цикл впендюрить - подсовывать массивчики по 8 байт за один раз - но мне уже лень )
Записан

S
Гость
« Ответ #20 : 11-05-2007 18:41 » 

Спасибо госпада. Приятно удивлен количеством ответов на тему в столь краткий срок, а главное тем что вы подсказали мне простой способ отражения байта (сдвиг аправо спереносом а затем сдвиг в лево с перносом). Теперь попробую составить свою програмку для TASMа.
Записан
RXL
Технический
Администратор

ru
Offline Offline
Пол: Мужской

WWW
« Ответ #21 : 11-05-2007 20:00 » 

Леха, справочник по командам глянь Улыбаюсь Команды сдвига все изменяют CF, но не все берут из него значение...

ROL:
b31 -> b0 -> ... -> b31 -> CF

RCL:
CF -> b0 -> ... -> b31 -> CF
Записан

... мы преодолеваем эту трудность без синтеза распределенных прототипов. (с) Жуков М.С.
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #22 : 11-05-2007 20:46 » 

RXL,
я глянул )

rol -
1) сдвиг  всех битов ... ляля тополя,
2) одновременно выдвигаемый бит становится значением флага переноса CF

пункт 2 я и использовал , у меня идёт команда  jnc

   rol eax,1
   jnc L1_1
   or dwdrig,80000000h
Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines