> И что самое интересное - в начале и в конце push / pop ecx, но ecx нигде не юзается?.. Это так память в стеке выделяется для переменной размера DWORD
Asterix Точняк, какой же я невнимательный... еще одно доказательство того что торопиться не стоит.. Но еще остался ebx, который можно портить не сохраняя если он не нужен далее, но без вложенности в main и без WPO такая неосторожность не показатель... А еще можно в стеке затирать аргументя main`а - ониж не юзаются и обойдемся вообще без пушей, но как говорится селяви.
Asterix Какой хитрый компиллер Если переменных больше одной, то все "по-человечески", sub-ом. А тут вон что творит Кстати, еще вот что интересно. Как-то видел что esp откатывался не через sub esp,xxx, а через add esp,0ffffffxxh. С чем это может быть связано?
_DEN_ Похоже на фрагмент выравнивания стека на 8\16 (обычно, для даблов и __m128), тока не add а and.
semen Не, именно add. Обычный откат для временных переменных. Вот только через add. Вот это и непонятно...
_DEN_ Скорее всего ошибаешься - поискал в куче листингов - add к esp на отрицательные числа нету, а вот and - дофига.
По поводу add esp, вместо sub. У этих команд есть опкоды со знаковым расширением непосредственного байтового операнда. Диапазон значений для знакового байта [-128..+127] Поэтому команда add esp,-128 может быть закодирована более коротким опкодом, чем sub esp,128.
Да - я ведь смотрел сишные листинги, а не дизассемблер, там как будет закодирована инструкция можно не увидеть, так-же как с npad 3 будет не 3 нопа... Кстати все-таки врядли, потому что запомнилось add esp,0ffffffxxh - а это явно не короткий вариант, хотя может ида так показывает...
jxx всеравно нужно ждать пока выполнится команда устанавливающая флаги и отреагирует предсказание, а в это время можно выполнить и mov (если остальные порты исполнения простаивают, и даже не один), возможно так он помогает перегруппировать мопы, или он вообще левый mov вставляет?
от вставки mov между операциями сравнения, выiгрыш если и будет, то только для mov (ну скажем операнды подоспеют). Как я заметил операции cmp/test/or и jxx/setxx в большинстве случаев выполняются одновременно (по крайней мере на AthlonXP), и даже если не одновременно (cmp al, bl\jmp eax)- для такой близкой перестановки и существует диспетчеризация комманд.
Я тоже вставляю mov перед jcc. Чтобы jcc не бежал впереди паровоза, провоцируя пенальти. Если это например jcc в конце цикла, то mov или другая инструкция, которая будет выполнена на следующей итерации, главное, чтобы она не требовала результатов предыдущего cmp/test и не изменяла флаги. И от пенальти избавляемся, и полезное действие делаем. Если такой полезной инструкции нет, то иногда просто mov ebp,ebp делаю.
Декодеры современных процессоров заглатывают и исполняют порой по 3 инструкции за такт, так-что для реальной-гарантированной задержки надо вставлять либо инструкцию которая параллельно с jxx не выполняется, либо две инструкции. На пайп тестах это бывает хорошо видно - добавил ты одну комманду mov, она как раз вместе cmp & jxx вместе оказывается в группе выполнения.
Чего то вы странные вещи говорите о jcc. На суперскалярных процессорах, jcc ничего не ждет и ничего не делает, кроме как засылает себя в branch предиктор и со спокойной совестью идет в отставку. Поэтому ее латентность = 0 или 1 такт. А установка флагов и работа бранч-предиктора идут на следующей стадии конвейера параллельно с обработкой последующих и возможно предыдущих инструкций. А длина конвейера как известно не менее 10 стадий, а в гипер-пайпланах и за тридцатник зашкаливает. Что это означает ? Это означает, что когда jcc только добралась до исполнительного блока, и уж тем более когда начинается проверка условия jcc - процессор уже не менее как 10 тактов занят подготовкой спекулятивного исполнения следующего за jcc кода (на основании предыдущего решения бранч-предиктора). И если предсказание оказалось не верным, то - труба - сбрасывай неверно загруженный конвейер и начинай грузить с другого адреса. И никакой mov тут не спасет (разве ж только div ) И дело тут не в тактах, а в количестве микроопераций, которые уже были спекулятивно загружены в конвейер после jcc и которые придется выбросить в случае ошибки предсказания.