вызываю: invoke XFunction,'bla-bla,bla',[var1] генерация кода: push [var1] Call $+12+5 db 'bla-bla,bla',0 Call [XFunction] при вызове такожего кода из другой части проги, происходит тоже самое. как или что сделать, что бы во втором и последующих случаях, строка не обьявлялась, а просто передавался бы её адрес? есть ли более оптимизированый макрос invoke?
Да: invoke XFunction,szBlaBlaBla,[var1] А если серьёзно, у S_T_A_S_ вроде макросы строят текст в глобальной таблице. Ну, может, на форуме фасма есть ещё что. Для масма макросы Four-F c такой фичей.
IceStudent где взять макросы S_T_A_S_'a ? я искал, не нашел. или он ими не хочет делиться,тормозя приход к Светлому Будущему?!
Такой вызов, конечно, удобен и нагляден, но не эффективен. Нарушаются сразу два принципа оптимизации: 1. Не смешивать код и данные 2. Избегать ненужных ветвлений
Это правило оптимизации branch prediction, о котором почему-то часто забывают Процессоры пытаются предсказывать не только джампы и колы, но и реты. Причем с предсказанием прямых jmp и call особых проблем нет, т.к. они всегда совершаются по фиксированному адресу (при первом проходе рулит статическое предсказание с небольшим штрафом = длине конвеера от фетча до выхода декодера ~5-6 тиков, а при последующих проходах уже никаких штрафов нет). А вот с возвратами как раз проблема, т.к. функция может вызываться из разных мест. Для предсказания адреса возврата во всех процах (начиная с PMMX) используется простейший механизм - return (address) stack buffer (RSB или RAS). Всякий раз как только проц встречает на выходе декодера (или T-кэша в P4) моп call, в RSB заталкивается адрес возврата = адресу этого call + длина инструкции. Соответсвенно для ret проц просто извлекает из RSB последний адрес, предполагая что данный ret соответсвует предыдущему call. Отсюда и правило соответсвия пар call и ret Intel: "Сalls and returns must be matched in pairs" AMD: "Always pair CALL and RETURN" Соответсвенно при использовании call без возврата, нарушается синхронизация RSB и последующие ret'ы будут предсказаны неверно. В приведенном примере, если XFunction вызывается из другой функции YFunction, то дойдя до ret этой функции проц вместо настоящего адреса возврата возьмет из RSB адрес строки 'bla-bla-bla' и будет пытаться повторно декодировать этот мусор
Понятно. Ну, код выше - с ним всё ясно. А насчёт пар - интересно. А как процессор относится к коду наподобие следующего? Код (Text): ; call Func1 ; call Func2 ; ... push @F push Func2 jmp Func1 @@: ; ... P.S. Сорри если оффтоп.
Разумеется, что ret'ы без call'ов также нарушают синхронизацию RSB. AMD считает это очевидным и не заостряет внимания на примерах. А писатели Intel решили указать на этот (видимо распространенный) прием особо - вот полный текст Assembly/Compiler Coding Rule 4: Near calls must be matched with near returns, and far calls must be matched with far returns. Pushing the return address on the stack and jumping to the routine to be called is not recommended since it creates a mismatch in calls and returns. Ну а как процессор "относится к коду" - да ему пофиг, он же камень Ему ж надо чем-то заняться, пока неизвестен адрес перехода. Вот он и начинает спекулятивно декодировать и исполнять инструкции на основе предсказанного адреса, но окончательное решение всегда принимается после исполнения jcc\jmp\call\ret. Если угадал - прекрасно (код уже загружен и частично исполнен), если не угадал - значит не судьба, придется сбрасывать весь конвеер, начинать декодирование с другого адреса и ждать не менее 10\20\30 тиков пока первая инструкция доберется по конвееру до исполнительного блока. Ну а если ret'ов больше чем call'ов и RSB опустошается, то мануалы молчат о том что делает проц при пустом RSB - по-видимому просто продолжает декодировать код, следующий за ret PS: RSB имеет ограниченную глубину - 12 в атлонах и 16 в пеньках, поэтому возможны также миспредикшены при рекурсивном вызове функций, особенно если они содержат вызовы других функций (см.мануалы по оптимизации AMD: Athlon x86 - 22007.pdf или Athlon64 - 25112.pdf)
Первоначальный вариант можно посмотреть здесь. Была ещё либа макросов, там возможностей больше, выкладывал и здесь и не форуме fasm, но всё это удалили. Могу на мыло отправить, если есть желание ковыряться. Сейчас это проблематично использовать из-за изменений в fasm.