Присматриваюсь к команде bsf ebx,eax Нужно получить поочередно все ненулевые биты в EAX... Так что, после каждой bsf сбрасывать бит в eax под номером ebx вручную чтоли отдельной командой?
Что то типа: В eax - значение которое проверяешь. Код (Text): xor ecx, ecx t: mov edx, 1 shl edx, cl and edx, eax jz nobit ... тут знаем что бит который в cl стоит nobit: inc ecx cmp ecx, 32 jb t
persicum Можно так Код (Text): xor ecx,ecx mov cl,32 a1: shl eax,1 jnc nobit ... тут знаем, что бит который в cl стоит nobit: loop a1 Здесь решалась похожая задача
Не господа-чуваки, так дело не пойдет. Известно, что ненулевых бит в eax мало, а то и вообще нет... 32 раза вертеть запаришься... вот код который у меня ща работает. Что бы хотелось улучшить: либо отказаться от btc вообще, либо заменить jmp на условный, чтобы не делать последний холостой оборот, когда битов уже заведомо нету оставшихся. Не приложу ума, как это можно сделать, иба btc флаг нуля не трогает, вообще убогие команды мля! Код (Text): @loop: bsf ebx,eax jz @quit // не нашла --- тут делаем свои темные делишки --- btc eax,ebx jmp @loop @quit:
persicum Если оптимизация по времени, то bs, bt достаточно медленные операции, а проверить на ноль можно и test eax,eax/jz Код (Text): test eax,eax jz exit; бит равных 1 нет совсем test eax,55555555h jz единичные биты нечетные и т.д.
Медленные то они медленные, но ведь там стоит по одной битовой команде, а это поди быстрее чем комбинации из нескольких там test или shr в цикле. Если я вставлю test, а в eax есть 5 бит, то пять раз этот test облажается и будет тормозить, зачем дополнительно тестить, если bsf сама ставит флаг нуля?
Не верю я, чтобы такой громоздкий метод дихотомии был быстрее одной команды bsf, какой бы тормозной она не была...
persicum Было предложено несколько вариантов, с "гребенкой", номера единичных битов обнаруживаются за 5 проверок, а не за 32 как с bsf Если не жалко памяти - можно организовать табличный поиск вообще одной командой jmp Table[eax*4]
Мне думается, что когда говорят, что битовые команды медленней логических, то это только для тех случаев, когда заранее известно, какие биты нужны и можно состряпать готовую маску заблаговременно. А если - как в моем случае - номера нужных бит заранее не известны, то имхо битовые команды должны быть быстее ясен глаз. Так, btc x,y видимо должно быцтрее работать чем x:=x xor (1 shl y) из паскаля... Не понял юмора... bsf нужный бит находится за одну проверку 16 гигов o: ?
persicum Разбить eax на 4 последовательных байта (собственно, al, ah бесплатно получаются). Построить 1 таблицу и четыре раза к ней обратиться. ЗЫ А вообще я что-то не врубаюсь, что собственно нужно: количество единичных битов или их позиции.
Вот именно позиции нужны, самих ненулевых бит немного в каждом eax. А точнее, нужно улучшить мой код, если это возможно, поскольку свое решение я уже приводил... Ну и вообще, компетентно предложить самый быстрый вариант и с гарантией, замерить тайминги и тики, латенцию типа. Короче, самое оптимальное решение задачи последовательного скана бит, когда число ненулевых бит невелико, но в принципе нужна работоспособность и для любого их числа вплоть до 32 штук
А внутри IMULя аж 32 сдвига и 32 сложения, теперь не жить и убицца головой ап стену... А если в al вдруг сидит несколько бит (а вдруг?), хотя это и маловероятно, но возможно...
persicum Код (Text): test eax,eax jz quit ;нет единичных бит совсем mov ecx,32 a1: add eax,eax setz bl jnc nobit ... тут знаем, что бит, который в cl стоит nobit: test bl,1 jnz quit; кончились единичные биты dec ecx jnz a1 quit:
Очень изобретательный вариант... А чем не устраивает самый простой? И покороче будет. Код (Text): xor ebx,ebx @lll: test eax,1 jz @nobit --- в ebx номер бита @nobit: inc ebx shr eax,1 jnz @lll Насчет shr не помню, может нужно с cl