зачем в ЯВУ нужны ebp фреймы если можно отсчитывать от esp?

Тема в разделе "WASM.BEGINNERS", создана пользователем GoldFinch, 7 дек 2008.

  1. GoldFinch

    GoldFinch New Member

    Публикаций:
    0
    Регистрация:
    29 мар 2008
    Сообщения:
    1.775
    Когда прога пишется на асме, удобно делать ebp фрейм, чтобы вместо
    push [esp+4]
    push [esp+4+4]
    push [esp+8+4]

    писать
    push [ebp+4]
    push [ebp+4]
    push [ebp+4]

    или даже
    push [arg1]

    Но зачем компиляторы ЯВУ делают ebp-фреймы? Им-то несложно отслеживать esp и подставлять необходимое смещение.
     
  2. Partner

    Partner Павел

    Публикаций:
    0
    Регистрация:
    28 фев 2008
    Сообщения:
    917
    Адрес:
    Los Angeles
    В некоторых компиляторах создание фреймов - это опция.
     
  3. meduza

    meduza New Member

    Публикаций:
    0
    Регистрация:
    15 авг 2008
    Сообщения:
    212
    GoldFinch
    1. esp очень "непостоянный", он очень часто меняется: при передаче параметров функции, при сохранении регистра, при создани временной переменной в стеке, итп... А ebp можно сразу установить каким нужно и без всяких перерасчетов обращаться к локальным переменным и аргументам, переданным в текущую функцию.
    2. Сейчас это не актуально, но в Win16, как писал Агнер Фог, прерывание таймера будет менять верхнее слово esp, когда это невозможно преугадать.
    3. просто удобней, а затраты на создание стекового фрейма очень незначительные. Это меньшее о чем вы должны беспокоится.
     
  4. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    GoldFinch

    Объяснение этому исключительно историческое: в 16-разрядных процессорах для адресации данных в памяти можно было использовать только регистры BX, BP, SI и DI. Остальные четыре регистра, в том числе SP, использоваться для адресации не могли.

    В 80386 уже появилась возможность адресоваться по любым регистрам, однако, чтобы её использовать, нужно было существенно переделывать компиляторы ("в лоб" переделать с 16- на 32-разрядный куда проще, чем заставить его использовать все возможности 32-разрядной архитектуры).
     
  5. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    Ну вообще-то есть ещё то обстоятельство, что адресация через esp занимает на один байт больше, чем через прочие регистры. В
    Код (Text):
    1. mov eax,[esp+4]
    2. mov eax,[ebp+4]
    первая инструкция занимает 4 байта (8B 44 24 04 - дополнительно включается байт SIB "24"), а вторая - только 3 (8B 45 04). Естественно, при адресации через ebp тратятся дополнительные байты на пролог/эпилог, но если обращений к локальным переменным много, получается выигрыш.
     
  6. green

    green New Member

    Публикаций:
    0
    Регистрация:
    15 июл 2003
    Сообщения:
    1.217
    Адрес:
    Ukraine
    GoldFinch
    Ф-ции с esp-адресацией неудобны при отладке - стек обратных вызовов после них получается ненадёжным.
     
  7. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    diamond
    Не через прочие, а как раз черех AX, CX, DX и SP или их 32-разрядные версии. А лишний байт возник как раз из-за расширения системы команд; в старом формате, без SIBа, задать эти четыре регистра в качестве компонента адреса было невозможно.

    В объёме памяти -- безусловно, а вот в скорости -- обычно нет. Скорость выполнения инструкций в современных процах не зависит как таковая от используемой адресации и длины кода команды. Другое дело, что более длинная процедура сожрёт больше кэша, а это может привести к падению производительности, но это уже косвенное влияние, оценить которое очень сложно.

    green
    Для компилятора нет проблем с отладкой, это не ручное написание процедуры на асме с ручным же отслеживанием состояния указателя стека.
     
  8. diamond

    diamond New Member

    Публикаций:
    0
    Регистрация:
    21 май 2004
    Сообщения:
    507
    Адрес:
    Russia
    SII
    16-битная и 32-битная адресации отличаются. В 16-битной вообще невозможно адресовать через AX, CX, DX и SP. А в 32-битной все регистры, кроме esp и ebp, эквивалентны, mov edx,[eax] и mov edx,[ebx] занимают по два байта.
    Это верно, по скорости прямого влияния нет, но есть косвенные - одно за счёт раздувания кэша, а другое за счёт освобождения ebp под другие нужды.
     
  9. SII

    SII Воин против дзена

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    diamond
    Да. Но регистры в полном смысле эквивалентными в 32-разрядном режиме не являются, что Вы, собственно, и сами раньше сказали, указав, что адресация через ESP требует большего объёма памяти под код команды. Ну а если заняться формированием адреса из нескольких компонентов (пара регистров, отклонение, множитель), то вообще кошмар получается :)

    Но возвращаясь к теме, повторю, что главная причина сохранения стековых фреймов -- историческая. Компиляторы были разработаны под неё, поскольку в 16-разрядном режиме иначе нельзя, и это продолжало тянуться, поскольку логику компиляторов существенно не меняли, а лишь дорабатывали. Чисто же технических проблем для отказа от EBP как базы фрейма не было никаких уже в 80386.
     
  10. _basmp_

    _basmp_ New Member

    Публикаций:
    0
    Регистрация:
    10 июл 2005
    Сообщения:
    2.939
    push ebp
    mov ebp,esp
    mov eax,[ebp] ; eax = ebp предыдущего фрейма (параметры/возврат/локали)
    mov eax,[eax] ; eax = ebp предпредыдущего фрейма

    только недавно сталкивался с такой штукой. При компиляции с оптимизацией прога слетала. Использовалось для улучшеного вывода сообщений, от чего отказываться не хотелось. Впрочем и так понятно как это может быть полезно. Есть и другие способы организации стека дающие другие бонусы.

    (те это не обязательно, а просто удобно иногда)
    ну и отлаживать безсорцово удобнее гораздо.
     
  11. bugaga

    bugaga New Member

    Публикаций:
    0
    Регистрация:
    1 июл 2007
    Сообщения:
    361
    это свидетельствует ток об ее неправельности, или отстойности копилятора. Я вон GCC перекомпилил с хардкорными опшенами
    так ексешко 400кб скинуло(а таг гдет 3метра весил)! Конечно для тесту я заново перекомпилил компилер улутшеным компилером.

    Как по мне - работает шустрее.

    К сожалению на
    попадало все... Там компиль по умолчанию в 3-х регистрах парамы передает. eax, ecx, edx, (то к чему я так привык в кагбе дельфе, да)) Благо на моих несложных прогах оно работает.