Локальные переменные: ESP или EBP?

Тема в разделе "WASM.ASSEMBLER", создана пользователем AsmGuru62, 6 дек 2006.

  1. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    Привет собратьям по разуму!

    Такой вот вопрос: когда в процедуре имеются локальные переменные, какой регистр лучше использовать для доступа? ESP или EBP? В документации INTEL указано, что ESP используется если не нужна отладочная информация и EBP - если она нужна. Неплохо было-бы узнать какая имплементация быстрее - или разницы нет? Дело в том, что использование ESP имеет по меньшей мере две проблемы:

    1. Генерируемый код больше по размеру

    2. Труднее вызвать Win32 API, так как если вызов происходит обычным образом:

    Код (Text):
    1. invoke HeapAlloc, [esp + loc1.hHeap], 1, 32
    PUSH каждого параметра "портит" ESP и следующий параметр оказывается не на месте. Приходится сначала грузить параметры в регистры, и затем только вызывать API. Или можно поправить ESP при передаче параметра:

    Код (Text):
    1. invoke HeapAlloc, [esp + loc1.hHeap + 8], 1, 32
     
  2. Quantum

    Quantum Паладин дзена

    Публикаций:
    0
    Регистрация:
    6 янв 2003
    Сообщения:
    3.143
    Адрес:
    Ukraine
    AsmGuru62
    Когда параметров и локальных переменных мало в большой и сложной функции (скажем, < 2), я стараюсь использовать esp для экономии регистра. Таким образом, ebp остаётся доступен для других операций. Если параметров и/или локальных переменных больше, то использую классический стековый фрейм. Для внутренних функций оптимальнее использовать сишное соглашение о вызове и параметры передавать не через push, а так, как это делает gcc - получается неплохой выйгрыш в скорости. Пример:
    Код (Text):
    1. mov [esp], param1
    2. mov [esp+4], param2
    3. mov [esp+8], param3
    4. call f
    Заметьте, что параметры можно пихать в любом порядке, в отличии от варанта push, что всегда помогает при оптимизации. Обратно "выпихивать" параметры, т.е. фиксить стек нет необходимости. Конечно, такое можно использовать только для сишных функций.
     
  3. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    Еще такая конструкция встречается (например, при работе со структурой)

    sub esp, N ;выделяем в стеке память под структуру размера N
    mov [esp+ofs1], ...;заполняем поля
    mov [esp+ofs2], ...
    ...
    call f

    Или еще так (толкаем в стек Float)
    sub esp, ...
    fstp [esp]
    call f
     
  4. fr0b-p

    fr0b-p New Member

    Публикаций:
    0
    Регистрация:
    1 окт 2006
    Сообщения:
    118
    crypto - у тебя точна такой вариант как у Quantum тока без купюр :)
     
  5. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    GCC - метод интересен, но если вызывать API, то такое не пройдёт, так как API на выходе поправляет ESP на величину nParams*4. А вообще, интересно.
     
  6. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    AsmGuru62
    Ты можешь на эту же величину nParams*4 увеличивать стек.
     
  7. crypto

    crypto Active Member

    Публикаций:
    0
    Регистрация:
    13 дек 2005
    Сообщения:
    2.533
    fr0b-p
    Можешь считать это цитированием классика :)