генерация кода by invoke в фасме

Тема в разделе "WASM.ASSEMBLER", создана пользователем dead_body, 10 дек 2005.

  1. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    вызываю:

    invoke XFunction,'bla-bla,bla',[var1]



    генерация кода:

    push [var1]

    Call $+12+5

    db 'bla-bla,bla',0

    Call [XFunction]



    при вызове такожего кода из другой части проги, происходит тоже самое. как или что сделать, что бы во втором и последующих случаях, строка не обьявлялась, а просто передавался бы её адрес? есть ли более оптимизированый макрос invoke?
     
  2. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine


    Да: invoke XFunction,szBlaBlaBla,[var1]



    А если серьёзно, у S_T_A_S_ вроде макросы строят текст в глобальной таблице. Ну, может, на форуме фасма есть ещё что. Для масма макросы Four-F c такой фичей.
     
  3. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    IceStudent

    где взять макросы S_T_A_S_'a ? я искал, не нашел. или он ими не хочет делиться,тормозя приход к Светлому Будущему?!
     
  4. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Поброди по форуму fasm'a, там много ещё интересного найдёшь.
     
  5. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Такой вызов, конечно, удобен и нагляден, но не эффективен.

    Нарушаются сразу два принципа оптимизации:



    1. Не смешивать код и данные

    2. Избегать ненужных ветвлений
     
  6. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка


    тут согласен.





    видно непонял, что-то.где тут ветвления?
     
  7. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Имеется ввижу ненужный call (если бы строки хранились в отдельном месте).
     
  8. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    К тому же этот call не имеет ret и нарушает принцип соответствия пар call+ret
     
  9. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    leo

    Это что за принцип такой? Что-то серьёзное или так, стиль программирования?
     
  10. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Это правило оптимизации 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' и будет пытаться повторно декодировать этот мусор
     
  11. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    Понятно. Ну, код выше - с ним всё ясно. А насчёт пар - интересно. А как процессор относится к коду наподобие следующего?
    Код (Text):
    1.  
    2.   ; call Func1
    3.   ; call Func2
    4.   ; ...
    5.   push @F
    6.   push Func2
    7.   jmp  Func1
    8. @@:
    9.   ; ...




    P.S. Сорри если оффтоп.
     
  12. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    Разумеется, что 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)
     
  13. IceStudent

    IceStudent Active Member

    Публикаций:
    0
    Регистрация:
    2 окт 2003
    Сообщения:
    4.300
    Адрес:
    Ukraine
    leo

    Спасибо. По твоим ответам можно составить неплохой FAQ по оптимизации :)
     
  14. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Первоначальный вариант можно посмотреть здесь.

    Была ещё либа макросов, там возможностей больше, выкладывал и здесь и не форуме fasm, но всё это удалили. Могу на мыло отправить, если есть желание ковыряться. Сейчас это проблематично использовать из-за изменений в fasm.
     
  15. dead_body

    dead_body wasm.ru

    Публикаций:
    0
    Регистрация:
    3 сен 2004
    Сообщения:
    603
    Адрес:
    Украина;г.Харьков;г.Н.Каховка
    S_T_A_S_

    dead_body@rambler.ru