Rambler's
Top100

Оптимизация программ на ассемблере. Часть 1

Автор: lonesome TSH/Digital Daemons
Дата: .01.2003
Раздел: Ассемблер вне ОС

В этой статье мы рассмотрим основные приемы оптимизации программ написанных на ассемблере. Напомню, что приступать к оптимизации есть смысл только тогда, когда программа уже практически окончательно написана и работает (причем правильно работает).

В большинстве случаев оптимизацию по скорости имеет смысл проводить только в участках программы, выполняющихся многие сотни и тысячи раз - циклах.

Обнуление регистров с помощью xor

Используйте команду xor для обнуления регистров. Например команда
xor eax, eax
ассемблируется в:
31 C0
, а mov eax, 0 - в:
B8 00 00 00 00

Занесение в регистр единицы

Оптимальнее использовать не mov REG, 1, а
xor REG, REG
inc REG
Эти две команды в сумме на два байта меньше чем соотвествующая команда присваивания

Выполнение циклов задом наперед

Один из самых важных приемов оптимизации цикла - это выполнение его задом наперед. Зачем? В большинстве случаев цикл имеет вид:
xor ecx, ecx
.loop:
...
inc ecx
cmp ecx, N
jl .loop

Но что представляет собой команда CMP X, Y? Эта команда выполняет вычитание Y из X и устанавливает флаги в соотвествии с результатом, но не сохраняет результат. Т.е. если вместо приращения ECX использовать уменьшение, то необходимость в команде CMP отпадает!

mov ecx, N
.loop:
...
dec ecx
jae .loop
Полученный таким образом цикл будет выполняться от N до 1

Развертывание циклов

Если тело цикла достаточно мало, то в цикле его можно повторить несколько раз, это избавит от такого же количества проверок и условных переходов

Использование регистра EAX

Очень многие команды имеют сокращенную форму - в том случае, когда один из операндов - регистр EAX. Это позволяет сэкономить один байт
Например:
xchg eax, ebx ассемблируется в:
93
а xchg ebx, ecx - в
87 D9

Использование команды LEA для быстрых арифметических вычислений

Команду LEA можно (и нужно) использовать для некоторых арифметических вычислений, например:
lea ecx, [eax+12] - ECX = EAX+12
lea eax, [ebx+ecx] - EAX = EBX+ECX
lea eax, [eax+eax*8] - EAX = EAX*9

Префиксы

Каждый префикс, например префикс переопределения сегмента, требует одного такта на декодирование и увеличивает программу на один байт.


Rambler's Top100