Дано двойное слово и указатель на память. Заполнить по указателю память размерами единичных и нулевых строк двойного слова например двойное слов 11101111011001110111110111111111b нулевые и единичные строки будут: 111111111 0 11111 0 111 00 11 0 1111 0 111 массив должен быть заполнен значениями 9,1,5,1,3,2,2,1,4,1,3 Приоритет в задаче - скорость.
Код (Text): mov eax,0EF677DFFh ;EAX: value mov esi,offset buff ;ESI: pointer xor ecx,ecx xor ebx,ebx xor edx,edx inc edx ;EDX: mask mov edi,edx ;EDI: what to search loop: test eax,edx setne cl cmp edi,ecx ;if bit changed setne bl ;change address add esi,ebx xor edi,ebx ;if address changed - XOR EDX,1 inc byte ptr[esi] shl edx,1 jnc loop
Пока так (с циклом): Код (Text): mov eax,11101111011001110111110111111111b mov edi,buffer mov ecx,eax shl ecx,1 xor eax,ecx mov ecx,31 shr eax,1 inc byte [edi] @@: shr eax,1 adc edi,0 inc byte [edi] dec ecx jnz @b
Абсолютно ровный код: Код (Text): flsz:;(eax - bit's str, edi - buf) mov ecx,eax xor eax,80000000h sar ecx,1 xor eax,ecx repeat 32 shr eax,1 inc byte [edi] sbb edx,edx;на атлоне это быстрее sub edi,edx;чем adc edi,0 end repeat ret
Black_mirror Код "ровный" но сильно тормозит на P4 - почти в 1.5 раза хуже, чем цикл bogrus'а. Причина - неудачное расположение inc byte [edi] = false dependence по флагам. Лучше ее поставить перед shr, а еще лучше заменить на add byte [edi],1. Тогда получается быстрее, чем в цикле - но не намного (< 15%). А вот существенный выигрыш на P4 получается опять-таки с SETcc. Но надо бы еще на P3 проверить - partial register все-таки.
Вариант с SETcc: Код (Text): macro xxx unroll { mov ecx,11101111011001110111110111111111b mov edi,buffer mov eax,ecx add eax,eax xor eax,ecx mov ecx,2 add byte [edi],1 xor edx,edx @@: test eax,ecx setnz dl add edi,edx add byte [edi],1 add ecx,ecx if unroll = 0 jnz @B ;вариант с циклом else repeat 30 ;вариант с разворотом test eax,ecx setnz dl add edi,edx add byte [edi],1 add ecx,ecx end repeat end if} Вариант с циклом: на P3 дает те же результаты, что и вариант bogrus, а на P4 на 20% лучше (204 против 248) и несколько лучше усовершенствованного варианта Black_mirror (216). Развернутый вариант (398 байт !): на P3 получается чуть хуже усовершенствованного варианта Black_mirror (130 против 125), но на P4 на 70% лучше (128 против 216). PS: попробовал варианты с BSF: ес-но сильная зависимость от числа строк в дворде. Разве только к 11й задачке подойдет для достаточно длинных строк.