проблема с макросом

Тема в разделе "WASM.ASSEMBLER", создана пользователем cresta, 14 янв 2006.

  1. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Добрый день.

    Люди, помогите с макросом. Никак не пойму их (макросов) философию :dntknw:

    Нужен макрос для вызова ф-ции не по имени (как в invoke), а по адресу в ячейке памяти.

    Примерно так:


    Код (Text):
    1. .data
    2.     dwFuncAddr  dd ?    ;адрес ф-ции
    3. .code
    4.  
    5.     AddrInvoke dwFuncAddr, param1, param2, param3, ...
    6.  
    7.     Чтобы разворачивалось в
    8.     push    param3
    9.     push    param2
    10.     push    param1
    11.     call    dwFuncAddr




    Заранее спасибо.
     
  2. halyavin

    halyavin New Member

    Публикаций:
    0
    Регистрация:
    13 май 2005
    Сообщения:
    252
    Адрес:
    Russia
    Попробуй это:
    Код (Text):
    1. macro AddrInvoke x,y
    2. {
    3.   common
    4.   stdcall [x],y
    5. }
     
  3. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Судя по common и {} это фасм.

    А для масма это как будет?
     
  4. S_T_A_S_

    S_T_A_S_ New Member

    Публикаций:
    0
    Регистрация:
    27 окт 2003
    Сообщения:
    1.754
    Вроде как для этого макрос не нужен, invoke сам должен справиться, если правильно прототип указать.

    Как-то так, но не уверен в правильности:
    Код (Text):
    1. .data
    2. dwFuncAddr:PTR PROTO :DWORD,:DWORD,:DWORD
    3. .code
    4. invoke dwFuncAddr 0, 1, 2


    Своё макрос invoke на masm реализовать - изврат тот ещё :)
     
  5. _BC_

    _BC_ БЦ

    Публикаций:
    0
    Регистрация:
    20 янв 2005
    Сообщения:
    759
    cresta

    А ты пользуй TASM и не знай горя:


    Код (Text):
    1. .model flat, stdcall
    2.     ...
    3. funcs   dd  1234 dup(?)
    4.     ...
    5.     call    [funcs+eax*4], 1, 2, 3, 4
     
  6. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Три варианта: прямой, косвенный и вызов через регистр. Тебе нужен косвенный.


    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap:none
    4.  
    5. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    6.  
    7. include \masm32\include\windows.inc
    8.  
    9. include \masm32\include\user32.inc
    10. include \masm32\include\kernel32.inc
    11.  
    12. includelib \masm32\lib\user32.lib
    13. includelib \masm32\lib\kernel32.lib
    14.  
    15. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    16.  
    17. proto02 typedef proto :DWORD, :DWORD
    18. pproto02 typedef ptr proto02
    19.  
    20. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    21.  
    22. .data
    23. szCaption       db "Caption", 0
    24. szText          db "Text", 0
    25.  
    26. pfnFunc dd offset Func
    27.  
    28. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    29.  
    30. .code
    31.  
    32. Func proc pText:LPSTR, pCaption:LPSTR
    33.     invoke MessageBox, NULL, pText, pCaption, MB_OK
    34.     ret
    35. Func endp
    36.  
    37. start:
    38.  
    39.     invoke proto02 ptr [Func], addr szText, addr szCaption
    40.  
    41.     invoke pproto02 ptr [pfnFunc], addr szText, addr szCaption
    42.  
    43.     mov edx, pfnFunc
    44.     assume edx:ptr proto02
    45.     invoke edx, addr szText, addr szCaption
    46.     assume edx:nothing
    47.    
    48.     invoke ExitProcess, 0
    49.  
    50. end start
     
  7. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Это если количество параметров варьируется от 1 до 10, получается 20 typedef'ов, 10 Func'ов :dntknw:

    Похоже макрос тут не получится.



    В общем немного подумал, и сделал одну ф-цию (CDECL), может кому пригодится:




    Код (Text):
    1. AddrFunc  PROTO C :DWORD, :VARARG
    2.  
    3. .data?
    4.     espVal  dd  ?
    5.     espAddr dd  ?
    6. .code
    7. AddrFunc proc C fnAddr:DWORD, params:VARARG
    8.     option prologue : none
    9.     option epilogue : none
    10.     m2m     espVal,[esp]
    11.     mov     espAddr,esp
    12.     add     esp,8
    13.     call    dword ptr[esp-4]
    14.     sub     esp,8
    15.     mov     esp,espAddr
    16.     m2m     [esp],espVal
    17.     ret
    18.     option prologue : prologuedef
    19.     option epilogue : epiloguedef
    20. AddrFunc endp
    21.  
    22. ;--------------------------------
    23. ;вызов:
    24.     invoke  GetProcAddress, hModule, SADD("MessageBoxA")
    25.     invoke  AddrFunc, eax, 0, addr szMessage, addr szCaption, 0




    Одна ф-ция и один proto для любого кол-ва параметров. И регистры не портит :)

    Возвращаемое значение как и положено, сидит в eax.
     
  8. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Так весь смысл invoke+proto в том и заключается, что проверяется кол-во параметров.
    Код (Text):
    1. proto00 TYPEDEF proto
    2. proto01 TYPEDEF proto :DWORD
    3. proto02 TYPEDEF proto :DWORD, :DWORD
    4. proto03 TYPEDEF proto :DWORD, :DWORD, :DWORD
    5. proto04 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD
    6. proto05 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
    7. proto06 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
    8. proto07 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
    9. proto08 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
    10. proto09 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
    11. proto10 TYPEDEF proto :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD, :DWORD
    12.  
    13.  
    14. pproto00 TYPEDEF PTR proto00
    15. pproto01 TYPEDEF PTR proto01
    16. pproto02 TYPEDEF PTR proto02
    17. pproto03 TYPEDEF PTR proto03
    18. pproto04 TYPEDEF PTR proto04
    19. pproto05 TYPEDEF PTR proto05
    20. pproto06 TYPEDEF PTR proto06
    21. pproto07 TYPEDEF PTR proto07
    22. pproto08 TYPEDEF PTR proto08
    23. pproto09 TYPEDEF PTR proto09
    24. pproto10 TYPEDEF PTR proto10
    Ну будет 20 typedef'ов - ну и что? А макрос тут просто не нужен.



    ЗЫ:
    Код (Text):
    1. invoke  AddrFunc, <font color="red]eax</font><!--color-->, 0, addr szMessage, addr szCaption, 0
    eax будет затёрт из-за addr
     
  9. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257




    Если eax будет перетираться, масм выдаёт предупреждение: register overwritten by invoke и отказывается компилить код. В этом случае можно просто сделать

    invoke AddrFunc, dwMsgBoxAddr,...

    Если же компилит - значит eax не будет портиться. Собственно, я проверял на трех функциях: 3, 4 и 10 параметров (OpenSCManager, MessageBox и EnumServicesStatusEx). eax не портится (смотрел в Olly). Все вызовы проходят успешно.
     
  10. Four-F

    Four-F New Member

    Публикаций:
    0
    Регистрация:
    31 авг 2002
    Сообщения:
    1.237
    Да, начёт "register overwritten by invoke" я забыл. А не затирается потому, что параметры глобальные - push offset. Если локальные переменные, то будет lea eax/push eax. Ну ладно - это ерунда.



    Я всё таки настаиваю на invoke+proto ;) Вот так будет более благообразно:
    Код (Text):
    1. .386
    2. .model flat, stdcall
    3. option casemap:none
    4.  
    5. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    6.  
    7. include \masm32\include\windows.inc
    8.  
    9. include \masm32\include\kernel32.inc
    10. includelib \masm32\lib\kernel32.lib
    11.  
    12. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    13.  
    14. proto04 typedef proto :DWORD, :DWORD, :DWORD, :DWORD
    15. pproto04 typedef ptr proto04
    16.  
    17. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    18.  
    19. .data?
    20.  
    21. pfnMessageBoxA pproto04 ?
    22.  
    23. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    24.  
    25. .data
    26. szCaption       db "Caption", 0
    27. szText          db "Text", 0
    28.  
    29. szUser32        db "user32.dll", 0
    30. szMessageBoxA   db "MessageBoxA", 0
    31.  
    32. ;:::::::::::::::::::::::::::::::::::::::::::::::::
    33.  
    34. .code
    35.  
    36. start proc uses ebx
    37.  
    38.     invoke LoadLibrary, addr szUser32
    39.     mov ebx, eax
    40.     invoke GetProcAddress, ebx, addr szMessageBoxA
    41.     mov pfnMessageBoxA, eax
    42.  
    43.     invoke pfnMessageBoxA, NULL, addr szText, addr szCaption, MB_OK
    44.  
    45.     invoke FreeLibrary, ebx
    46.     invoke ExitProcess, 0
    47.  
    48. start endp
    49. end start
     
  11. cresta

    cresta Active Member

    Публикаций:
    0
    Регистрация:
    13 июн 2004
    Сообщения:
    2.257
    Ага, это у же другое дело, промежуточных функций не надо.

    ОК. Спасибо.