API функции портят регистры

Тема в разделе "WASM.BEGINNERS", создана пользователем BenQ, 11 ноя 2005.

  1. BenQ

    BenQ New Member

    Публикаций:
    0
    Регистрация:
    24 окт 2005
    Сообщения:
    47
    Уважаемые, скажите почему API функции затирают регистры?

    Ведь по идее, они должны затирать лишь eax т.к. в нем содержится результат выполнения функции. Но все наооборот - эти чертовы функции трут все регистры, кроме ebp, а мне нужны затираемые регистры. Неужели мне каждый вызов функции обрамлять кодом pushad/popad??? есть ли более оптимальный путь?
     
  2. IceStudent

    IceStudent Active Member

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

    readme New Member

    Публикаций:
    0
    Регистрация:
    2 июл 2005
    Сообщения:
    271
    Адрес:
    Russia
    esi edi и ebp тока сохраняют
     
  4. Asterix

    Asterix New Member

    Публикаций:
    0
    Регистрация:
    25 фев 2003
    Сообщения:
    3.576
    readme

    > esi edi и ebp тока сохраняют



    и только?

    а ebx, esp ? :derisive:
     
  5. leo

    leo Active Member

    Публикаций:
    0
    Регистрация:
    4 авг 2004
    Сообщения:
    2.542
    Адрес:
    Russia
    А eip,cs,ds,es,ss,fs,gs ? :derisive:

    A FPU-стек ?



    Правильнее было бы сказать, что в общем случае не сохраняются регистры eax,edx и ecx.

    Поэтому ес-ли нужно их сохранить, то перед вызовом API их нужно либо запушить, либо затолкать в локальные [esp+X] или [ebp+X], либо в сохраняемые регистры ebx,edi,esi,ebp
     
  6. SDragon

    SDragon New Member

    Публикаций:
    0
    Регистрация:
    6 июн 2005
    Сообщения:
    133
    Адрес:
    Siberia
    Еще нужно push'ить esi, edi, ebp (+ кажется, ebx) в начале WndProc и восстанавливать по окончании. Если при возврате в системный код значение этих регистров окажется изменено, под Win XP программа вылетет с ошибкой.
     
  7. harley

    harley New Member

    Публикаций:
    0
    Регистрация:
    28 июн 2005
    Сообщения:
    11
    Адрес:
    Russia
    Есть такой способ решения проблемы: пишем функцию с именем, похожим на библиотечную, например так:



    _MsgBox:

    push ebx

    push ecx

    call MessageBoxA

    pop ecx

    pop ebx

    ret



    и потом ее вызываем каждый раз вместо библиотечной. И регистры целы...
     
  8. q_q

    q_q New Member

    Публикаций:
    0
    Регистрация:
    5 окт 2003
    Сообщения:
    1.706
    harley

    А как же параметры уже размещенные в стеке?