Wake of Gods Forum | Форум Во Имя Богов

Full Version: Исследование героев
You're currently viewing a stripped down version of our content. View the full version with proper formatting.
Частенько в коде Героев встречаются команды типа:
lea eax, [eax + 8*eax]
.

Я правильно понимаю, что они нужны для упрощения написания вычислений (вместо:
push ebx
push edx
mov ebx, eax
mov edx, 0
mov eax, 8
mul ebx
add eax, ebx
pop edx
pop ebx
)?

При выполнении есть ли разница между этими командами?


И такой тупой вопрос: можно ли в Иде изменять команды не через Hex-view и как?
Да, примерно так и есть. Разница очевидна - с командой LEA ты не изменяешь другие регистры и не работаешь со стеком.
А когда процессор одинаково быстро выполняет эту lea-команду и "нормальный" код?
LEA-команды выполняются за один такт обычно или даже две-три такие команды за такт, а "нормальный код", который ты привёл, во много раз дольше, в лучшем случае в пять-десять раз.
Но процессору всё равно же надо вычислить, чему равно, eax+8*eax, он что, как-то по-особому вычисляет это в lea-команде?
Именно по-особому.
К тому же в твоём "нормальном" примере изменяются три регистра, а значит их нельзя использовать в других командах, что замедляет выполнение программы (регистры-то часто используемые). Используется стек, то есть идёт обращение к кеш-памяти, на что отводятся дополнительные такты процессора, а в случае с полным кешем, этот кеш нужно выгружать в оперативную память (десятки тактов). Используются три подряд команды mov, что полностью блокирует на несколько тактов блок ввода-вывода, хотя это и не важно, так как дальше идёт длительная команда MUL. Эта команда MUL сама по себе плохая, особенно если в твоём случае блокирует использование сразу трёх регистров и все конвееры процессора или ядра останавливаются, ожидая завершения этой команды.

А команда LEA специально оптимизирована для вычисления формул вида
REG = REG+REG*2N+CONST.
Современные процессоры вычисляют за такт несколько таких команд.
Тогда понятно и то, почему там eax+8*eax вместо 9*eax.
Спасибо.
Если память мне не изменяет, то множители (2^N) могут быть только 2, 4 и 8. Этот модификатор команды появился только с i386. Ну и понятно, что умножение на 2^N суть сдвиг на N битов влево. Т.е. *9 и *8 две большие разницы (должно быть). Хотя современные процессоры и умножают уже за 1-2 такта.
(05.10.2010 00:51)ZVS Wrote: [ -> ]Если память мне не изменяет, то множители (2^N) могут быть только 2, 4 и 8.
Ну, может быть и 1. То есть РЕГ = РЕГ + РЕГ. Ноль не считается.

Не знаю как самые-самые последние процессоры, но пару лет назад умножение было не меньше 3-4 тактов. Правда могло проходить сразу два умножения параллельно. Это про 32-разрядное умножение.
РЕГ+РЕГ - это стандартный модификатор, который был еще в 80x86, а множители появились, начиная с i386 специально для быстрого обращения к элементам массивов.
Может, кому-нибудь пригодится:

по адресу [6919480]+1170n+137020, где n - номер героя,
находится байт, в котором хранится 1, если герой спит (кнопка "Усыпить/разбудить героя" на карте приключений), иначе - 0.
(01.09.2010 15:15)MOP Wrote: [ -> ]Вот длл с более подробным (откомментированным) исходником. Создаёт триггер на лечение Палаткой.
большая просьба прислать мне почтой на randommaps (@) yandex (.) ru. ибо период полураспада файлообменников очень мал и сцылка уже нерабочая
Вот исходник:

Я уже отправил SAG-у файл на почту.
Подскажите, пожалуйста, как затереть/вызвать определенное диалоговое окно (алгоритм). Например, дабы вместо окна таверны вызывалось окно рынка.
Элементарно. Менять таблицу jmp-ов для case - а идентификатора зданий.
Reference URL's