IDA Pro за работой
Причем, цикл выровнен по адресам, кратным 10h (команды "LEA ESI,[ESI+0]" и "LEA EDI,[EDI+0]" используются для выравнивания), что с одной стороны хорошо, а с другой — не очень. Начиная с процессоров поколения P6 (к которым, в частности, принадлежит Pentium Pro, Penium-II) и AMD K5, выравнивание циклов требуется только тогда, когда целевой переход попадает на команду, расщепленную двумя линейками кэш-памяти первого уровня, длина которых в зависимости от процессора составляет 32, 64 или даже 256 байт. В противном случае наблюдается существенное снижение быстродействия.
Компилятор MS VC вообще не выравнивает циклы, поэтому их быстродействие зависит от воли случая — попадет ли первая инструкция цикла на "расщепляющий" адрес или… не попадет. Компилятор GCC выравнивает циклы, но по слишком ретивой стратегии, всегда подтягивая их к адресам, кратным 10h. Это хорошо работает на первопнях, но вот на более современных процессорах команды, расходующиеся на выравнивание, занимают лишнее место и впустую съедают производительность (особенно на вложенных циклах, где они выполняются многократно).
Зато, в отличии от своего конкурента, GCC "догадался" использовать команду "MOVZX EAX, AL", только вот _зачем_ она ему понадобилась — не понятно. Команда "MOVZX" пересылает значение из источника в приемник, дополняя его нулями до 16- или 32-бит (в зависимости от разрядности). Но ведь в нашем случае старшие биты регистра EAX _уже_ равны нулю, поскольку компилятор _сам_ обнулил их инструкцией "XOR EAX,EAX". Следовательно, команда "MOVZX EAX,AL" совершенно не нужна и со всей своей очевидностью избыточна.
Интересно, изменилось ли что-нибудь в новых версиях? Компилируем программу с помощью GCC 3.4.2 и смотрим полученный результат:
.text:080484C0 CRC proc near
.text:080484C0
.text:080484C0 arg_0 = dword ptr 8
.text:080484C0 arg_4 = dword ptr 0Ch
.text:080484C0
.text:080484C0 55 push ebp
.text:080484C1 89 E5 mov ebp, esp
.text:080484C3 8B 4D 0C mov ecx, [ebp + arg_4]
.text:080484C6 53 push ebx
.text:080484C7 31 C0 xor eax, eax
.text:080484C9 8B 5D 08 mov ebx, [ebp+arg_0]
.text:080484CC 31 D2 xor edx, edx
.text:080484CE EB 04 jmp loc_80484D4
.text:080484D0
.text:080484D0 loc_80484D0:
.text:080484D0 02 04 13 add al, [ebx+edx]
.text:080484D3 42 inc edx
.text:080484D4
.text:080484D4 loc_80484D4:
.text:080484D4 39 CA cmp edx, ecx
.text:080484D6 7C F8 jl short loc_80484D0
.text:080484D8 0F B6 C0 movzx eax, al
.text:080484DB F7 D8 neg eax
.text:080484DD 5B pop ebx
.text:080484DE C9 leave
.text:080484DF C3 retn