Макро FUNC masm32

Тема в разделе "WASM.WIN32", создана пользователем MirrorBlack, 6 мар 2009.

  1. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Здравствуете.
    Возникла маленькая проблема при использовании макроса FUNC.
    Если написать нечто подобное:
    .if (FUNC(lstrcmpi,esi,addr szService) == FALSE)
    ...
    .elseif (FUNC(lstrcmpi,esi,addr szCOMObject) == FALSE)
    ...

    то при компиляции получим следующее:

    push offset szService
    push esi
    call lstrcmpi
    or eax,eax
    jnz @F

    ...

    push offset szCOMObject
    push esi
    call lstrcmpi
    @@: ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    or eax,eax
    jnz @F

    Как видно второй lstrcmpi отработает только если отработал первый :dntknw:

    Не менее странно (с моей точки зрения) работает и следующее:
    invoke MessageBox,0,FUNC(LoadString,wc.hInstance,1000,addr buf1,128),FUNC(LoadString,wc.hInstance,1001,addr buf2,128),MB_OK

    При компиляции получим следующее:

    push 128
    push offset buf2
    push 1001
    push wc.hInstance
    call LoadString
    push 128
    push offset buf1
    push 1001
    push wc.hInstance
    call LoadString

    push MB_OK
    push eax ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    push eax ;!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
    push 0
    call MessageBox

    Хочется понять, это "косяк", или так и должно быть?
     
  2. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    MirrorBlack Попробуй так
    Код (Text):
    1. .if  
    2.  (FUNC(lstrcmpi,esi,addr szService) == FALSE)
    3.     ...
    4. .elseif
    5.  (FUNC(lstrcmpi,esi,addr szCOMObject) == FALSE)
    6.    ...
    По поводу второго - ты явно перестарался. Я имею ввиду два макроса в одном инвоке. Так и должно быть, посмотри, как определен этот макрос.
     
  3. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Еще немножко макросов, из моей коллекции.
    Код (Text):
    1. ;Этот макрос позволяет вызывать функции стандартным способом, если адрес функции находится в переменной
    2. ; Пример:  xinvoke _NtOpenSection,offset hPhyMem,6h,offset oAttr      ---->>>  _NtOpenSection - это переменная в которой хранится адрес ф-ции
    3. xfn macro fname, params: VARARG
    4.     count = 0
    5.     FOR param, <params>
    6.         count  = count+1
    7.         @CatStr(var,%count) TEXTEQU <param>
    8.     ENDM
    9.     REPT count
    10.         push @CatStr(var,%count)
    11.         count = count -1
    12.     ENDM
    13.     push fname
    14.     pop eax
    15.     call eax
    16. ENDM
    17. ;Этот макрос позволяет исключить лишний переход на таблицу импорта
    18. exfn macro fname, params: VARARG
    19.     count = 0
    20.     FOR param, <params>
    21.         count  = count+1
    22.         @CatStr(var,%count) TEXTEQU <param>
    23.     ENDM
    24.     nparam = count
    25.     REPT count
    26.         push @CatStr(var,%count)
    27.         count = count -1
    28.     ENDM
    29.     %echo @CatStr(_imp__,fname,@,%(nparam*4))
    30.     extern @CatStr(_imp__,fname,@,%(nparam*4)): dword
    31. call    @CatStr(_imp__,fname,@,%(nparam*4))
    32. ENDM
    33. ; Это макрофункция подобна макросу xinvoke
    34. ; Пример: mov _NtOpenSection, xf(_GetProcAddress, hnt, offset @NtOpenSection)
    35. xf macro fname, params: VARARG
    36.     count = 0
    37.     FOR param, <params>
    38.         count  = count+1
    39.         @CatStr(var,%count) TEXTEQU <param>
    40.     ENDM
    41.     REPT count
    42.         push @CatStr(var,%count)
    43.         count = count -1
    44.     ENDM
    45.     push fname
    46.     pop eax
    47.     call eax
    48.     exitm <eax>
    49. ENDM
    50. ;Макрос позволяет писать в строчку вызов функции сразу присваевая значение переменной
    51. ; Пример: mov _NtOpenSection, f(GetProcAddress, hnt, offset @NtOpenSection)
    52. f MACRO fname:VARARG
    53. fn fname
    54. exitm <eax>
    55. ENDM
    Единственное, они не кушают директиву addr. Мне было лено мудрить и я оставил так..
     
  4. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Aspire
    Написал, и вот результат:
    Service1C.asm(28) : error A2008: syntax error : eax
    Компилятор не понял что это за .if без условия.
    Да и вторая строка (FUNC(lstrcmpi,esi,addr szService) == FALSE) тоже не вызвала оптимизма.
    А такой вариат:
    .if \
    (FUNC(lstrcmpi,esi,addr szService) == FALSE)
    ...
    .elseif \
    (FUNC(lstrcmpi,esi,addr szCOMObject) == FALSE)
    ...

    Выполняется как и раньше.

    По второму - может и переборщил. Но посмотреть как определён макрос не могу, т.к. раньше их не писал, и как они работают имею только самое поверхностное представление.
     
  5. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Противопоказано.
     
  6. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    MirrorBlack
    Вобщем, я фсе это к тому, что если написать

    Код (Text):
    1. @@:
    2. mov ebx, FUNC(GetProcAddress, edi, esi)
    То все это развернется в
    Код (Text):
    1. push esi
    2. push edi
    3. call GetProcAddress
    4. @@:
    5. mov ebx, eax
    То есть метка будет совсем не там, где ты ее ожидаешь увидеть. Поэтому внимательнее с макросами. И если не понимаешь как они работают, то лучше не юзай.

    Писал по памяти, проверь.
     
  7. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Aspire
    Спасибо за пример. Можно сказать глаза открыл.
    Т.е. это можно принять за постулат, или есть обходные пути?
     
  8. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    MirrorBlack
    А не.. вспомнил.
    Если вот так
    Код (Text):
    1. @@: mov ebx, FUNC(GetProcAddress, edi, esi)
    То все будет как я написал выше. Поэтому нужно поставить метку выше, вот так
    Код (Text):
    1. @@:
    2. mov ebx, FUNC(GetProcAddress, edi, esi)
    и будет все ок.

    А макрос .if у тебя пишется в одной строке, поэтому это и не работает.
     
  9. Aspire

    Aspire New Member

    Публикаций:
    0
    Регистрация:
    19 май 2007
    Сообщения:
    1.028
    Напиши с помощью cmp/je/jne... так как тебе нужно.
     
  10. MirrorBlack

    MirrorBlack Алексей

    Публикаций:
    0
    Регистрация:
    21 июн 2008
    Сообщения:
    249
    Адрес:
    Moscow
    Aspire

    cmp/je/jne...

    Так и писал всю дорогу.
    Однако сейчас возникла необходимость изменить данные в моей старой программе, а это 19 asm файлов ~5000 строк каждый.
    Писал 3 года назад, а сейчас и вспомнить не могу где что...
    Вот и решил облагообразить свои труды с помощью macro :)
    Ну что делать, будем грызть гранит macro.