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

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

  1. SII

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

    Публикаций:
    0
    Регистрация:
    31 окт 2007
    Сообщения:
    1.483
    Адрес:
    Подмосковье
    persicum
    Один байт отклонения (displacement) -- оно рассматривается как число со знаком.
     
  2. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Как заметил Mika0x65
    Видимо стековые фреймы - это атавизм из тех далёких времён.
     
  3. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Ща изучил, как это дело устроено в Дельфах =)))

    1) Если процедура НЕ содержит директивы ASM, то компилер генерит код с ESP.
    Переменным заводятся ячейки, адресуемые в теле как [esp], [esp+1], [esp+2]... А массивы индексируются как [esp+eax+NNN]

    2) Если процедура содержит директиву ASM (где дельфоасмеры в принципе могут класть в стек и очень даже кладут), то переменным заводятся адреса [ebp-1], [ebp-2]... А массивы индексируются как [ebp+eax-NNN]

    Так что разработчики сочли ESP адресацию *предпочтительнее* EBP адресации. Также делаем вывод, что она совершенно безопасна. Единственное что удивляет, какое преимущество имеет add esp,-N перед sub esp,N для небольших N вроде теже три байта... А они лепят непочеловечески add esp,-N вначале...
     
  4. SII

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

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

    persicum
    Естественно, безопасна и предпочтительнее: лишний регистр обычно бывает нелишним, да и действий в прологе и эпилоге подпрограммы становится меньше...
     
  5. Serg50

    Serg50 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2010
    Сообщения:
    48
    мне показалось, что с ESP удобнее делать временные переменные, например:
    Код (Text):
    1. sub  esp, sizeof STRUCa
    2. assume esp: PTR STRUCa
    3. ....
    4. типа Mov [esp].Fielda, eax
    5. invoke Func,..., esp
    6. ....
    7. add  esp, sizeof STRUCa
    Работает нормально, но неясно, насколько это нужно. Я это использовал для создания всяких временных структур в большой процедуре инициализации серии контролей. Но конечно если есть push/pop то нужно быть внимательным.

    percicum
    Немного не по теме, но если ты любитель повозиться с Delphi. Я тут "разбираюсь" с одной DLL написанной в Delphi(если Ida не врет), и меня поразило использование fastcall. В чем смысл? Ведь почти во всех случаях первое что делается в процедуре, это регистры сохраняются в локальных переменных! Или это был старый Delphi?
     
  6. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Ну да =)))
    Сначала fastcall, а потом почти всегда
    push esi
    push edi
    push ebx

    В x86 нельзя как в других архитектурах push imm8

    В опщем, некоторые пускают сразу в дело фасткольные eax, edx, ecx, но я не люблю когда мне навязываются еще и имена регистров, например в конце длинной процедуры, принимающий первый параметр как указатель результата, делать mov [eax],ebx както не хорошо, цеж аккумулятор!

    В win64 вроде еще и не такие фастколы, а совершенно огромные плюс еще регистры MMX в конце =)))
    Вот и скажи в чем смысл?
     
  7. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Понял я наконец смысл fastcall в дельфи.
    Процедуры могут свободно изменять регистры eax edx ecx, и они же являются параметрами. А раз можно их менять, то и незачем в стеке сохранять. А в win64 для первых четырех параметров, передаваемых через регистры, еще и резервируется место в стеке, чтобы можно было их туда положить и юзировать через esp/ebp. Вот это тоже смешно.
     
  8. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    n0name, есть и OllyDbg, а Ida часто мусор тыкает, напр. куча локальных переменных которых там попросту нету; наверное у меня плохие настройки или непривычки к ней.
    cppasm, murder "mov ebp,esp" & "pop ebp" = leave <- единственный плюс, который мне виден в этой комманде.
    persicum, кидайте вы тот Delphi: я дурею от "Constant 0 converted to NIL", фы нету разницы и т.д.
     
  9. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    Стековые фреймы позволяют адресовать локальные переменные независимо от дна стека(рег. Esp). Иначе например отладка станет ацкой.
     
  10. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    Clerk, в состоянии ацки можно много почерпнуть. Для своих программ это слишком, но даже простой push-pop за пару млн. повторов дает свои доли. Все зависит от желания проникнуть, или же попросту писать пышки-пустышки.
     
  11. Clerk

    Clerk Забанен

    Публикаций:
    0
    Регистрация:
    4 янв 2008
    Сообщения:
    6.689
    Адрес:
    РБ, Могилёв
    edemko
    У вас наверно в ядре проблем небыло никогда. Если ваш дров будет почемуто падать, а в нём не будут использоваться стековые фреймы вы поймёте какой это великогеморный процесс - отладка.
     
  12. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    Признаюсь, мне далеко до написания топлива т.е. драйверов, а без EBP трудно полю(ukr)бе.
    В сырцах фасма Grysztar часто использует EBP "не по назначению". Правильно, есть всегда другие регистры, где-то можно увельнуть.
     
  13. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    A мож выделять стек с запасом, тада и не будет адски сложной отладки?
    Вместо push писать mov [esp+size+4*N], где N это номер вложенности push
     
  14. persicum

    persicum New Member

    Публикаций:
    0
    Регистрация:
    2 фев 2007
    Сообщения:
    947
    Альтернативный подход, вместо push писать в область стекового мусора ниже фрейма, но Винда или отладчик могут его потереть?
     
  15. DevilDevil

    DevilDevil Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2007
    Сообщения:
    101
    persicum,
    Не п*зди. В Delphi используется стандартный пролог/эпилог и адресация через EBP. Я могу допустить (но только допсутить, потому что новых версий не видел), что в новых версиях оптимизатор на малом использовании локальных переменных может сэкономить на прологе/эпилоге

    Serg50,
    да, в этом смысл fastcall. а не fastcall в Delphi
    Регистры сохраняются в локальные переменные только в двух случаях:
    1) Это Debug, и чтобы не потерять переменные их юзают как локальные
    2) так счёл оптимизатор

    persicum,
     
  16. DevilDevil

    DevilDevil Member

    Публикаций:
    0
    Регистрация:
    14 ноя 2007
    Сообщения:
    101
    Serg50,
    1) Это Debug, и чтобы не потерять переменные их юзают как локальные
    2) так счёл оптимизатор


    persicum,
    да, в этом смысл fastcall. а не fastcall в Delphi
     
  17. edemko

    edemko New Member

    Публикаций:
    0
    Регистрация:
    25 ноя 2009
    Сообщения:
    454
    Можно и так:
    Код (Text):
    1. proc hehe, param1:dword, paramN:dword, ioResult:dword
    2.         ...
    3.         mov     eax,[ioResult]
    4.         mov     [eax],ebx
    5.         ret
    6. endp
    Вызов:
    Код (Text):
    1.         stdcall hehe,1,2,esp,0xDEADCODE
    2.         cmp     eax,ERR_CONSTANT
    3.         pop     eax
    4.         je      .error_label
    Как видим, переменная есть и нет :)
     
  18. Serg50

    Serg50 New Member

    Публикаций:
    0
    Регистрация:
    17 фев 2010
    Сообщения:
    48
    DevilDevil
    Ниже типичный пример входа в процедуру. Не уверен насчет Debug-а, но оптимизатоцией здесь похоже и не пахло :)

    Код (Text):
    1. CODE:004C31D0 sub_4C31D0                    proc near                     ; ...
    2. CODE:004C31D0
    3. CODE:004C31D0 var_C                         = dword ptr -0Ch
    4. CODE:004C31D0 var_8                         = dword ptr -8
    5. CODE:004C31D0 var_4                         = dword ptr -4
    6. CODE:004C31D0 arg_0                         = dword ptr  8
    7. CODE:004C31D0
    8. CODE:004C31D0                               push ebp
    9. CODE:004C31D1                               mov ebp, esp
    10. CODE:004C31D3                               add esp, 0FFFFFFF4h
    11. CODE:004C31D6                               push ebx
    12. CODE:004C31D7                               push esi
    13. CODE:004C31D8                               push edi
    14. CODE:004C31D9                               mov [ebp+var_C], ecx
    15. CODE:004C31DC                               mov [ebp+var_8], edx
    16. CODE:004C31DF                               mov [ebp+var_4], eax
    17. CODE:004C31E2                               mov eax, [ebp+var_4]
    18. CODE:004C31E5                               cmp dword ptr [eax+18h], 0
    19. CODE:004C31E9                               jnz short loc_4C323A
    Оговорюсь, что я не совсем уверен, что это было Delphi, но Ida относит множество системных процедур к библиотеке: BDS 2005-2006 and Delphi6-7 Visual Component Library. При таком использовании Fastcall выигрыш кажется весьма сомнительным. Persicum упоминал EBX, ESI & EDI, и мне помнилось, что Delphi именно ими пользовалось, но я ей пользовался весьма давно...
     
  19. murder

    murder Member

    Публикаций:
    0
    Регистрация:
    3 июн 2007
    Сообщения:
    628
    Вот ещё про ebp тема была

    http://www.wasm.ru/forum/viewtopic.php?id=10363
     
  20. Freeman

    Freeman New Member

    Публикаций:
    0
    Регистрация:
    10 фев 2005
    Сообщения:
    1.385
    Адрес:
    Ukraine
    в фасме можно переопределить пуш/поп и работу с локальными переменными, параметрами, чтобы юзался esp, а не ebp и автоматом пересчитывались смещения.
    но, как было сказанно, отладка тогда - геморой, да и профит подобного извращения сомнителен.