Здравствуете. Возникла маленькая проблема при использовании макроса 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 отработает только если отработал первый Не менее странно (с моей точки зрения) работает и следующее: 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 Хочется понять, это "косяк", или так и должно быть?
MirrorBlack Попробуй так Код (Text): .if (FUNC(lstrcmpi,esi,addr szService) == FALSE) ... .elseif (FUNC(lstrcmpi,esi,addr szCOMObject) == FALSE) ... По поводу второго - ты явно перестарался. Я имею ввиду два макроса в одном инвоке. Так и должно быть, посмотри, как определен этот макрос.
Еще немножко макросов, из моей коллекции. Код (Text): ;Этот макрос позволяет вызывать функции стандартным способом, если адрес функции находится в переменной ; Пример: xinvoke _NtOpenSection,offset hPhyMem,6h,offset oAttr ---->>> _NtOpenSection - это переменная в которой хранится адрес ф-ции xfn macro fname, params: VARARG count = 0 FOR param, <params> count = count+1 @CatStr(var,%count) TEXTEQU <param> ENDM REPT count push @CatStr(var,%count) count = count -1 ENDM push fname pop eax call eax ENDM ;Этот макрос позволяет исключить лишний переход на таблицу импорта exfn macro fname, params: VARARG count = 0 FOR param, <params> count = count+1 @CatStr(var,%count) TEXTEQU <param> ENDM nparam = count REPT count push @CatStr(var,%count) count = count -1 ENDM %echo @CatStr(_imp__,fname,@,%(nparam*4)) extern @CatStr(_imp__,fname,@,%(nparam*4)): dword call @CatStr(_imp__,fname,@,%(nparam*4)) ENDM ; Это макрофункция подобна макросу xinvoke ; Пример: mov _NtOpenSection, xf(_GetProcAddress, hnt, offset @NtOpenSection) xf macro fname, params: VARARG count = 0 FOR param, <params> count = count+1 @CatStr(var,%count) TEXTEQU <param> ENDM REPT count push @CatStr(var,%count) count = count -1 ENDM push fname pop eax call eax exitm <eax> ENDM ;Макрос позволяет писать в строчку вызов функции сразу присваевая значение переменной ; Пример: mov _NtOpenSection, f(GetProcAddress, hnt, offset @NtOpenSection) f MACRO fname:VARARG fn fname exitm <eax> ENDM Единственное, они не кушают директиву addr. Мне было лено мудрить и я оставил так..
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) ... Выполняется как и раньше. По второму - может и переборщил. Но посмотреть как определён макрос не могу, т.к. раньше их не писал, и как они работают имею только самое поверхностное представление.
MirrorBlack Вобщем, я фсе это к тому, что если написать Код (Text): @@: mov ebx, FUNC(GetProcAddress, edi, esi) То все это развернется в Код (Text): push esi push edi call GetProcAddress @@: mov ebx, eax То есть метка будет совсем не там, где ты ее ожидаешь увидеть. Поэтому внимательнее с макросами. И если не понимаешь как они работают, то лучше не юзай. Писал по памяти, проверь.
Aspire Спасибо за пример. Можно сказать глаза открыл. Т.е. это можно принять за постулат, или есть обходные пути?
MirrorBlack А не.. вспомнил. Если вот так Код (Text): @@: mov ebx, FUNC(GetProcAddress, edi, esi) То все будет как я написал выше. Поэтому нужно поставить метку выше, вот так Код (Text): @@: mov ebx, FUNC(GetProcAddress, edi, esi) и будет все ок. А макрос .if у тебя пишется в одной строке, поэтому это и не работает.
Aspire cmp/je/jne... Так и писал всю дорогу. Однако сейчас возникла необходимость изменить данные в моей старой программе, а это 19 asm файлов ~5000 строк каждый. Писал 3 года назад, а сейчас и вспомнить не могу где что... Вот и решил облагообразить свои труды с помощью macro Ну что делать, будем грызть гранит macro.