8.3.2. Использование команды LEA
Команда LEA может использоваться для трёхоперандного сложения (но только сложения, а не вычитания).
lea eax, [ebx + edx]
Команда LEA может использоваться для сложения значения регистра с константой или вычитания константы из значения регистра. В данном случае вычитание возможно, т.к. оно рассматривается как сложение с отрицательной константой. Результат может быть помещён в тот же или другой регистр (кроме регистра ESP). Такой способ используется для сохранения флагов, т.к. команда LEA, в отличие от команд ADD, SUB, INC и DEC, не меняет флаги.
lea eax, [eax + 1] ; Сохраняем флаги lea eax, [ebx – 4]
Команда LEA может использоваться для быстрого умножения на константы 2, 3, 4, 5, 7(?), 8, 9. Адрес, загружаемый командой LEA, может быть суммой двух регистров, один из которых может быть умножен на константу 2, 4 или 8. Поэтому комбинируя умножение и сложение можно получить вышеперечисленные константы. Третье слагаемое может быть константой.
lea eax, [eax * 4 + eax] ; EAX = EAX * 5 lea eax, [ebx * 8 + ecx – 32]
8.3.3. Замена команд
Вместо команды AND лучше использовать команду TEST, если нужен не результат, а проверка. Команда TEST лучше спаривается. Команда TEST также может быть использована для проверки на равенство нулю.
test eax, eax jz <метка> ; Переход, если EAX = 0
Если за командой CALL сразу же следует команда RET, замените эти команды командой JMP. Вызываемая процедура осуществит возврат по адресу возврата, переданному вызывающей процедуре.
call dest jmp dest ret
Команду CBW можно заменить засылкой нуля, если расширяемое число положительное. Команду CDQ можно заменить засылкой нуля, если расширяемое число положительное, или парой команд MOV + SAR, если знак расширяемого числа не известен. Недостаток – команды XOR и SAR меняют флаги.
cdq xor edx, edx cdq mov edx, eax sar edx, 31
Вместо команд инкремента и декремента можно использовать команду LEA.
Сложение и вычитание с константой можно заменить командой LEA.
Вместо умножения и деления на степень числа 2 используйте сдвиги.
Умножение и деление на константу можно заменить командой LEA или сочетанием команд сдвига и команд сложения и вычитания.
Деление на константу можно заменить умножением на константу.
Обнуление регистров производится с помощью команды XOR.
xor eax, eax ; EAX = 0 при любом значении EAX, которое было до этой команды
Не используйте команду MOVZX для чтения байта – это требует 3 тактов для выполнения. Заменой может служить такая пара команд, выполняющаяся за 2 такта:
xor еах, еах mov al, <источник>
Засылку непосредственного операнда в ячейку памяти можно производить через регистр – такие команды лучше спариваются.
mov x, 1 mov eax, 1 mov x, eax mov [ebx], 1 mov eax, 1 mov [ebx], eax
Аналогично команды PUSH и POP, работающие с ячейкой памяти, можно заменить парой команд MOV + PUSH или POP + MOV.
push x mov eax, x push eax pop x pop eax mov x, eax
Do'stlaringiz bilan baham: |