Война миров - ассемблер против си


Листинг2 результат трансляции crc() компилятором MS VC++ 6.0


Сразу бросается в глаза, что компилятору не хватило регистров (!) и счетчик контрольной суммы зачем-то задвинулся в локальную переменную. Впрочем, это не сильно сказалось на производительности, поскольку задвижение произошло _после_ выхода из цикла, но сам факт! А ведь, чтобы исправить ситуацию, всего-то и требовалось заменить "MOV byte ptr [ESP+5+var_1],CL/MOV EAX,[ESP+1+var_1]/AND EAX, 0FFh" на "MOVZX EAX,CL", что _гораздо_ короче и _намного_ быстрее, особенно, если n невелико и функция вызывается большое количество раз.

Следующее замечание: компилятору потребовалось целых 5 (!) регистров, в то время как для решения данной задачи вполне достаточно 3х: один — на сумматор CRC, один — на указатель и еще один — на адрес конца.

Ассемблер пример, с ручной оптимизацией приведен ниже:

 

 00000000: 51              push   ecx

 00000001: 8B4C240C        mov    ecx,[esp+arg_p]

 00000005: 8B542408        mov    edx,[esp+arg_n]

 00000009: 03CA            add    ecx,edx

 0000000B: 33C0            xor    eax,eax

 0000000D: EB03            jmps   000000012

 0000000F: 0201            add    al,[ecx]

 00000011: 41              inc    ecx

 00000012: 3BCA            cmp    ecx,edx

 00000014: 72F9            jb     00000000F

 00000016: 59              pop    ecx

 00000017: C3              retn




Начало  Назад  Вперед



Книжный магазин