слушайте, покажите условие последнего обсуждения, ато, похоже оно уже не из #1. а рыть все 4 стр лениво
qqwe Всё то же. Без переходов 85 байт Код (Text): movd xmm0,eax shufps xmm0,xmm0,0 mov cl,4 rol eax,cl push eax rol eax,cl push eax rol eax,cl push eax rol eax,cl push eax movups xmm1,[esp] xorps xmm0,xmm1 movaps xmm1,xmm0 psllq xmm1,2 orps xmm0,xmm1 movaps xmm1,xmm0 psllq xmm1,1 orps xmm0,xmm1 movaps xmm1,xmm0 psllq xmm1,4 andps xmm0,xmm1 pmovmskb eax,xmm0 add esp,16 add ax,1 sbb eax,eax
murder, mov cl,4 в конечном итоге спасает 2 байта, что не так принципиально; можете пустить коммент по коду: интересно?
У нас не sse4.1 - не проверю: Код (Text): rol eax,4 pinsrd xmm1,eax,3 rol eax,4 pinsrd xmm1,eax,2 rol eax,4 pinsrd xmm1,eax,1 rol eax,4 pinsrd xmm1,eax,0
edemko Там в принципе то же, что и в #93 Приводим регистры к виду eax = 87654321h xmm0 = 87654321876543218765432187654321h xmm1 = 76543218654321875432187643218765h Потом ксорим xmm0 c xmm1 и находим нулевые тетрады.
Код (Text): mov eax,$87654321 ; пример без совпадений movd xmm0,eax ; $87654321 shufps xmm0,xmm0,0 ; $87654321'87654321'87654321'87654321 mov cl,4 rol eax,cl ; $76543218 push eax rol eax,cl ; $65432187 push eax rol eax,cl ; $54321876 push eax rol eax,cl ; $43218765 push eax movups xmm1,[esp] ; $76543218'65432187'54321876'43218765 add esp,16 ; стек дальше не используем xorps xmm0,xmm1 ; $87654321'87654321'87654321'87654321 ; $76543218'65432187'54321876'43218765 ; xor-тетрады 8(остальные аналогично): ; 7 1 6 2 5 3 4 4 /* ; дальше пошел спать movaps xmm1,xmm0 psllq xmm1,2 orps xmm0,xmm1 movaps xmm1,xmm0 psllq xmm1,1 orps xmm0,xmm1 movaps xmm1,xmm0 psllq xmm1,4 andps xmm0,xmm1 pmovmskb eax,xmm0 add ax,1 sbb eax,eax */
Код (Text): movaps xmm1,xmm0 psllq xmm1,2 ;Совмещаем старшую половину каждой тетрады с младшей orps xmm0,xmm1 ;получаем пары битов (3 or 1, 2 or 0) movaps xmm1,xmm0 psllq xmm1,1 ;Совмещаем старшую половину каждой пары с младшей orps xmm0,xmm1 ;получаем логическую сумму битов тетрады 3 or 1 or 2 or 0 ;Таким образом если тетрада равна 0, то получаем 0 иначе 1 movaps xmm1,xmm0 psllq xmm1,4 ;совмещаем суммы так, чтобы они оказались в старшем бите andps xmm0,xmm1 ;Если одна из сумм равна 0, то в старшем бите одного из байтов окажется 0 pmovmskb eax,xmm0 add ax,1 ;если ax=-1, то eax=-1 sbb eax,eax ;иначе eax=0
Мастер! Работает, я проверил Я то алгоритм поиска нулевых тетрад взял по аналогии с алгоритмом Фогнера, для поиска конца строки. А вот, что можно проверять не старший, а младший бит тетрады не додумался.
56 байт, чуть улучшенный код Black_Mirror'а Код (Text): xor edx,edx mov cl,4 bts edx,eax repeat 7 shr eax,cl bts edx,eax end repeat shrd eax,edx,16 and eax,edx popcnt eax,eax ror eax,cl cdq xchg eax,edx
medstrax1 и оно работает?! если and eax,edx даёт не 0, значит были совпадающие тетрады, мне кажется далее должен быть dec eax, а не ror, но тогда получается 55 байт
Да, код действительно нерабочий, сори, поторопился. Правильнее будет вместо shrd eax,edx,16 and eax,edx писать shld eax,edx,16 xor eax,edx cwde Увы, те же 57 байт...
Мой вариант, пока 66 (65 - edited) байт - работаю над инициализацией... Код (Text): ; EAX - DWORD with 8 nibbles ; result: eax is 0 if there are at least two the same nibbles - -1 overwise ; Part I: convert nibbles into bytes and create temp array on stack @@IsSameNibbles: mov ebx,eax mov ecx,0F0F0F0Fh shr ebx,4 and ebx,ecx and eax,ecx mov esi,esp mov edi,esp push 7*2 pop ecx std stosd xchg eax,ebx stosd rep movsd cld stosd ; any junk stosd ; any junk dec ecx ; Part II: try to find each nibble in next "array" @@IsSameNibbles2: lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb ; Obtain result @@IsSameNibbles3: inc edi sub edi,esp cmc sbb eax,eax @@IsSameNibbles4:
Пока что только достиг 59 байт... Код (Text): ; EAX - DWORD with 8 nibbles ; result: eax is 0 if there are at least two the same nibbles - -1 overwise ; Part I: convert nibbles into bytes and create temp array on stack push 7*2+1 mov edi,esp pop ecx mov esi,edi std stosd and eax,0F0F0F0F0h xor [esi],eax shr eax,4 stosd rep movsd cld dec ecx ; Part II: try to find each nibble in next "array" lodsb mov edi,esi ; Initialization repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb lodsb inc edi repne scasb ; Obtain result inc edi sub edi,esp cmc sbb eax,eax