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

Discussion in 'WASM.BEGINNERS' started by BenQ, Nov 11, 2005.

  1. BenQ

    BenQ New Member

    Blog Posts:
    0
    Joined:
    Oct 24, 2005
    Messages:
    47
    Уважаемые, скажите почему API функции затирают регистры?

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

    IceStudent Active Member

    Blog Posts:
    0
    Joined:
    Oct 2, 2003
    Messages:
    4,300
    Location:
    Ukraine
  3. readme

    readme New Member

    Blog Posts:
    0
    Joined:
    Jul 2, 2005
    Messages:
    271
    Location:
    Russia
    esi edi и ebp тока сохраняют
     
  4. Asterix

    Asterix New Member

    Blog Posts:
    0
    Joined:
    Feb 25, 2003
    Messages:
    3,576
    readme

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



    и только?

    а ebx, esp ? :derisive:
     
  5. leo

    leo Active Member

    Blog Posts:
    0
    Joined:
    Aug 4, 2004
    Messages:
    2,542
    Location:
    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

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

    harley New Member

    Blog Posts:
    0
    Joined:
    Jun 28, 2005
    Messages:
    11
    Location:
    Russia
    Есть такой способ решения проблемы: пишем функцию с именем, похожим на библиотечную, например так:



    _MsgBox:

    push ebx

    push ecx

    call MessageBoxA

    pop ecx

    pop ebx

    ret



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

    q_q New Member

    Blog Posts:
    0
    Joined:
    Oct 5, 2003
    Messages:
    1,706
    harley

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