ESP vs EBP. Выбор базы для адресации.

Тема в разделе "WASM.ASSEMBLER", создана пользователем Serg50, 24 фев 2010.

  1. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    можно писать отказавшись от пушей. Хотя класть в мусор сомнительно, но во фрейм совсем не гимор, и ESP никуда не уплывет.
     
  2. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    А зачем вобще регистр Ebp. Зачем вобще инструкция Push, если есть Mov :lol:
     
  3. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Мда, если писать в мусор, то первый же call все убьет... А если вместо пушей писать во фрейм, то все ништях будет, тока опкоды подлинше...
     
  4. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Clerk
    Шоб ebp сыкономить для продуктивной работы, а не для статической базы типа ss cs, шоб не был таким гумном как последние два. Мне регистров всегда не хватает и всегда решается задача чтобы разместить все в решистрах, а в память писать тока конечный результат.
     
  5. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    persicum
    Не убъёт. Поток будет работать, пока стек валидный, никакие сепшены его не порушат. С камнем аналогично, пока исключение двойной ошибки не возникнет, он будет вызывать шлюзы.
     
  6. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    я под словом мусор имел ввиду всего лишь область памяти ниже указателя esp, куда можно писать не меняя ESP адресуясь как [esp-4], [ESP-8]...
     
  7. PowerASM

    PowerASM New Member

    Публикаций:
    0
    Регистрация:
    27 мар 2010
    Сообщения:
    59
    persicum
    а что тогда мешает перед первым же call поставить sub esp, n
     
  8. Z3N

    Z3N New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2009
    Сообщения:
    812
    От push можно безболезненно отказаться. Так будет даже полезней, особенно в процедурах где много бранчей. В таких процедурах лучше отказаться от пушей вообще (ну, не считая пушей перед каллами). У меня была две мечты, легкая реализация фастакала и процедура без ебп. Первое я недавно нашёл, а вот достойной реализации адресации через ебп я пока не видел :dntknw:
     
  9. DevilDevil

    DevilDevil Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2007
    Сообщения:
    101
    Serg50,
    Дело в том, что в Delphi несколько подопций Debug-а. И люди часто оставляют всё как есть, не доводя до "идельной скорости". В целом лично я в этом не вижу ничего плохого. В критичных процедурах - да, в целом нет.

    В данной ситуации как раз Debug. Т.е. запускаешь ты например свою прогу и в определённый момент захотел поставить брейкпоинт. Если бы в данном случае не использовать стек, то локальные переменные (var_C, var_8, ...) просто не будут видеться. Я думаю, что в С++ так же обстоит дело. Другое дело в С++ часто используется "Release" и вызов не fastacall, а cdecl. Оправдано тогда вызывать fastcall если всёравно юзается стек в большинстве случаев ? Не знаю. Возможно специалисты в Borland сочли, что юзер будет больше внимания уделять опциям компилятора перед "Релизом" или "Дебагом". В любом случае о производительности вызовов сложно говорить сейчас, когда оптимизатор Delphi сильно отстаёт от оптимизаторов C++.

    Будем надеяться, что Embarcadero проработает и этот вопрос. Уже сейчас в freepascal оптимизация значительно лучше, чем в Delphi. вот
     
  10. Z3N

    Z3N New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2009
    Сообщения:
    812
    Простите, имел в виду esp.
    Дельфи видел только мельком (IDE), но по моему там так же как и в VS можно переключаться между релиз и дебаг. Я прав? И в релиз переключателе не должно быть никаких дебаг дефиниций, но это моя логика... :). А код у дельфи просто ужас. Вот код, который мне приходиться видеть довольно часто.
    Псевдокод
     
  11. AsmGuru62

    AsmGuru62 Member

    Публикаций:
    0
    Регистрация:
    12 сен 2002
    Сообщения:
    689
    Адрес:
    Toronto
    В Студии 2005 в "Release" локальные автоматом идут через ESP и вызовы - _fastcall.
     
  12. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    AsmGuru62
    Фастколл он же не резиновый, если много параметров то в стек класть все равно придется. Что будет тада с локальными через ESP?
     
  13. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Ну еще адрес возврата
     
  14. Serg50

    Serg50 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2010
    Сообщения:
    48
    Увидел еще одно оригинальное применение ESP: параметры процедуре передавались через стек, но загонялись не командами PUSH, а что-то вроде MOV [ESP+nn], Par. При этом в начале вызывающего кода делался фрейм общий для локальных и передаваемых параметров. Прога явно оптимизировалась компилятором - часть параметров помещалась в регистры за 2-3 вызова до использования, но что это за компилятор так и не понял.
     
  15. Mika0x65

    Mika0x65 New Member

    Публикаций:
    0
    Регистрация:
    30 июл 2005
    Сообщения:
    1.384
    Serg50
    gcc так любит делать.
     
  16. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Serg50
    Классная система для рекурсии получается =)))
    фрейм переполнится уже при 2-3 вызовах...

    Придумали им EBP и однобайтовые пуши, а они мятежные свищут бури...
     
  17. l_inc

    l_inc New Member

    Публикаций:
    0
    Регистрация:
    29 сен 2005
    Сообщения:
    2.566
    Похоже здесь так и не упомянули про ещё одно довольно полезное свойство при использовании ebp (стандартный пролог/эпилог). А именно регенерация стека. Если функция попортит стек лишними push'ами, то программа не рухнет при возврате, т.к. фрейм будет восстановлен в эпилоге. В частности это даёт возможность не восстанавливать стек при cdecl-вызовах.
     
  18. Ykidia

    Ykidia Member

    Публикаций:
    0
    Регистрация:
    21 июн 2005
    Сообщения:
    99
    Адрес:
    Санкт-Петербург
    А не надо никаких лишних пушей делать, тогда и проблем не будет. Надо просто заранее выделить место в стеке таким образом, чтобы никакие пуши уже были не нужны.
    Код (Text):
    1. LifGetKeywordID:
    2.                 ;------------------------------------------
    3.                 ; GKID Workspace
    4. GKIDWS          struc
    5. gkidws_begin = $
    6. GKIDTmpregESI   dd      ?
    7. GKIDTmpregEBX   dd      ?
    8. GKIDSymbolCnr   dd      ?
    9. GKIDKeywordID   dd      ?
    10. GKIDKeywordLen  dd      ?
    11. GKIDSymbolPtr   dd      ?
    12. GKIDTemplatePtr dd      ?
    13. GKIDTemplates   dd      00100h - (GKIDTemplates - gkidws_begin) dup(?)
    14. gkidws_tmplts_size = $ - GKIDTemplates
    15. gkidws_size = $ - GKIDTmpregESI
    16.                 ends
    17.                 ;------------------------------------------
    18.                 ; GKID Subroutine
    19.  
    20.                 push    eax
    21.  
    22.                 ; ------ initializing GKID Workspace
    23.                 mov     eax, ecx
    24.                 mov     ecx, gkidws_size / 4
    25. LifGKID_005:
    26.                 push    dword ptr 0
    27.                 loopd   LifGKID_005
    28.                 mov     ecx, eax
    29.                 mov     [esp].GKIDTmpregESI, esi
    30.  
    31.                 ; ------ subroutine body start
    32.                 ; <...> some ebanishe code
    33.  
    34.                 ; example using GKID Workspace
    35.                 mov     [esp].GKIDKeywordLen, eax
    36.                 mov     eax, [esp].GKIDTmpregEBX
    37.                 mov     [esp].GKIDKeywordID, eax
    38.                 mov     [esp].GKIDSymbolPtr, edi
    39.  
    40.                 ; <...> some ebanishe code
    41.                 ; ------ subroutine body end
    42.  
    43.                 mov     esi, [esp].GKIDTmpregESI
    44.  
    45.                 lea     esp, [esp + gkidws_size]
    46.                 pop     eax
    47.  
    48.                 ret
    В этой вырезке видно, что доступ к локалке осуществляется через структуру - [esp].имя_переменной. Тут же можно определить названия для параметров, к-рые находятся выше локалки и адреса возврата. Понадобится еще один регистр - втыкаем еще переменную в структуру и ни в коем случае даже и не думаем, что надо пересчитывать какие-то смещения, компилятор сам все сделает. Кроме того, переменные вовсе необязательно инициализировать, если это не нужно, вместо инициализации просто sub esp, gkidws_size и все. Не нравица пользовать esp - делаем все то же самое, но с ebp (но тогда неудобно инициализироваться имхо). И - еще раз - никаких пушей в теле!
     
  19. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Ykidia
    Тоесть глупо расходовать память ?
    Так резервируйте себе сотни магабайт под код, который использует килобайты в нормальных условиях :lol:
     
  20. Ykidia

    Ykidia Member

    Публикаций:
    0
    Регистрация:
    21 июн 2005
    Сообщения:
    99
    Адрес:
    Санкт-Петербург
    Clerk
    Не надо передергивать. Заранее выделяется ровно столько места, сколько нужно.
    Что есть глупое расходование (неважно чего)? Постоянный pushad/popad в начале/конце каждой подпрограммы - это глупое расходование памяти, учитывая, что не во всех подпрограммах обязательно используются все регистры? А может, постоянное отслеживание правильного порядка и необходимости индивидуальных push/pop в начале/конце каждой подпрограммы - это глупое расходование времени при каждой попытке что-либо модифицировать в коде?
    Или лучше делать лихорадочный push/pop в теле подпрограммы, пытаясь таким образом компенсировать нехватку регистров, подстраивая под это безобразие свой алгоритм, после чего ни о какой ясности кода или желаемой скорости не может быть и речи?
    А о том, что, при использовании push/pop в теле, эти самые push/pop зачастую многократно вложенные, мы, после такого компостирования мозгов, конечно же забываем, мечтая о том, что "как мало моей проге надо" и "как она быстро работает".
    И еще - ничто не мешает заранее выделенное место в стеке использовать по-разному, но это очередное компостирование мозгов на любителя. Я ленивый и мой компостер в применении к своим мозгам работает очень туго. Для трудоголиков и просто любителей поонан... покомпостировать себе мозги вроде клерка вышеописанное мною конечно же не подходит :)