flat assembler
Message board for the users of flat assembler.
Index
> Macroinstructions > New powerfull invoke Goto page 1, 2 Next |
Author |
|
dead_body 05 Aug 2007, 23:39
please more exaples, and what this invoke can, that old invoke can't?
|
|||
05 Aug 2007, 23:39 |
|
Blid 06 Aug 2007, 19:20
;thanks for reply .
;invoke GetTickCount,[szbuffer] ;use "dw [hwnddlg]" and any from: dword,Dword,DWORD,dw,d,D,DW,Dw ;will be: ;push DWORD PTR SS:[EBP-1C] ;call [GetTickCount] ;------------------------------------------------------------ ;invoke GetTickCount,addr szbuffer ;use "addr [hwnddlg]" or any from: addr,Addr,ADDR ;this like at standart kit: ;LEA EDX,DWORD PTR SS:[EBP+8] ;PUSH EDX ;call [GetTickCount] ;------------------------------------------------------------ ;invoke GetTickCount,word [mytime.wMinute] ;use "word [mytime.wMinute]" or any from: word,Word,WORD,w,W ;will: ;XOR EDX,EDX ;LEA DX,WORD PTR SS:[EBP+8] ;PUSH EDX ;call [GetTickCount] ;------------------------------------------------------------ ;next ;invoke GetTickCount,word [mytime.wMinute],word [mytime.wHour] ;will: ;XOR EDX,EDX ;LEA DX,WORD PTR SS:[EBP+C] ;PUSH EDX ;LEA DX,WORD PTR SS:[EBP+8] ; (!)no xor edx,edx; mov dx,var = only one xor ;PUSH EDX ;call [GetTickCount] ;------------------------------------------------------------ ;next ;invoke GetTickCount,byte [mytime.wMinute],word [mytime.wHour] ;will: ;xor edx,edx ;mov dx,word [mytime.wHour] ;push edx ;xor edx,edx ;! xor need ;mov dl,byte [mytime.wMinute] ;push edx ;call [GetTickCount] ;------------------------------------------------------------ ;next ;invoke GetTickCount,word [mytime.wMinute],byte [mytime.wHour] ;will: ;xor edx,edx ;mov dl,byte [mytime.wHour] ;push edx ;mov dx,word [mytime.wMinute] ;! xor edx,edx not need ;push edx ;call [GetTickCount] ;------------------------------------------------------------ ;next (this trick was in standart kit): ;invoke GetTickCount,<invoke GetTickCount,[szbuffer]> ;will: ;push dword [szbuffer] ;call [GetTickCount] ;push eax ;call [GetTickCount] ;------------------------------------------------------------ ;at last you do not need include extended headers ;------------------------------------------------------------ |
|||
06 Aug 2007, 19:20 |
|
vid 06 Aug 2007, 19:23
blid: check this case, and issue warning if someone uses it:
Code: invoke ABC, edx, addr something |
|||
06 Aug 2007, 19:23 |
|
Blid 06 Aug 2007, 19:30
i do not understend you fully (i am not engl.)
;================================================ Do not use edx, in this case! You should understud : if edx, uses for storing adress of var, do not use it in arguments. If you can not remember i or you may add check for yhis case in macro. Or use other register , for example ECX! |
|||
06 Aug 2007, 19:30 |
|
vid 06 Aug 2007, 19:49
that's what i was talkin about. If someone uses it by mistake, after it was modified by "addr", then throw in some assembling error - it is obviously a bug
|
|||
06 Aug 2007, 19:49 |
|
Blid 06 Aug 2007, 20:04
it is not a bug!
it is special property of macros. ok, forgot it. Do you like this macro or not ? I wait you answer at percent scale , for example 45%. The maxium is 100% . |
|||
06 Aug 2007, 20:04 |
|
vid 06 Aug 2007, 20:11
there already is macro in standard macro package that does more than your macro, so it would be 25% for me. You can change my mind by providing some useful feature that standard call macros don't have
by the way, add support for literal strings: Code: invoke DbgPrint, "abcdefg" |
|||
06 Aug 2007, 20:11 |
|
Blid 06 Aug 2007, 20:18
;--------------------------------------------------------------------------
you may be never use the GetSystemTime and sprintf to print time in dword format. ;--------------------------------------------------------------- i was thinking about it! I can make this, add function to create label for this string. But string will be in code among commands,before 'jmp' or 'call'. I try to place this strings in .data section, more than one cannot. Can you help me, this will be good macros! |
|||
06 Aug 2007, 20:18 |
|
vid 06 Aug 2007, 20:45
current tomasz's macro already support nested calls. Strings are usually declared in code section, if you don't want to enforce usage of "idata"/"udata" on users of your macro.
|
|||
06 Aug 2007, 20:45 |
|
dead_body 07 Aug 2007, 01:12
so we have one advantage.
stack balance and ability to push... bytes words... I am for 30%. Do nested calls, then will se. |
|||
07 Aug 2007, 01:12 |
|
Blid 07 Aug 2007, 07:28
to dead_body:
the call's already nested !: 'There are no limits for the depth of nesting the procedure calls.' Or I do not understand something? This thing you are bear in mind? ;------------------------------------------------------------------------------- to vid: "if you don't want to enforce usage of "idata"/"udata" on users of your macro." - i do not understand. Please use simple words, you words i should look for it in dictionary. It is very slow .:=).And i do not get answer on my question. ;------------------------------------------------------------------------------- |
|||
07 Aug 2007, 07:28 |
|
vid 07 Aug 2007, 10:22
sorry, i will try to use simple words.
search forum for "idata", to learn about "idata" macro. Quote: And i do not get answer on my question what was your question again? I can't find it. |
|||
07 Aug 2007, 10:22 |
|
dead_body 07 Aug 2007, 22:03
Quote:
so I can, write: invoke API_name,<cinvoke API_name2,arg1,arg2>,<stdcall API_name3,arg5,arg6> |
|||
07 Aug 2007, 22:03 |
|
daluca 08 Aug 2007, 06:32
Hi, to Blid:
here is a thread I post some time ago about a overload of the invoke macro that uses lists to put all strings in one place: http://board.flatassembler.net/topic.php?t=6864 I think that the "idata" means that you have to provide actually two macros like I did. There is no Easy way to put strings declared in code anywhere else. Maybe a switch mecanism between sections would be useful. |
|||
08 Aug 2007, 06:32 |
|
Blid 08 Aug 2007, 07:59
thanks to all for reply!
to vid: i had understand. ok.I will search it later. And this new invoke will show warning message, if you try to use edx for argument (dx,dh,dl too): Code: macro invoke function*,[arg] { ;------------------------------------- ;useful (example): ; invoke GetTickCount,[szbuffer],addr szbuffer,w [mytime],<invoke GetSystemTime,esi>,\ ; b [szbuffer],dw [szbuffer] ;with out esp disbalance common local parsed_var,edx_zero edx_zero = 0 reverse parsed_var = 0 if ~arg eq if arg eqtype [ebp+0] parsed_var = 1 push dword arg else match type some,arg \{ parsed_var = 1 if type in <addr,Addr,ADDR,> replace addr, ,Addr, ,ADDR lea edx,[arg] edx_zero =0 restore addr,Addr,ADDR push edx end if if type in <b,B,byte,BYTE,Byte> replace b, ,byte, ,BYTE, ,Byte, if edx_zero <= 2 xor edx,edx end if mov dl,arg edx_zero = 3 restore b,byte,BYTE,Byte push edx end if if type in <word,Word,WORD,w,W> replace w,Word,W,Word if edx_zero = 0 xor edx,edx end if mov dx,arg dx_zero = 2 push edx restore w,W end if if type in <dword,Dword,DWORD,dw,d,D,DW,Dw> replace d,dword,dw,dword,D,dword,DW,dword,Dw,dword push arg restore d,D,dw,DW,Dw end if if type eq invoke arg push eax edx_zero =0 end if \} end if if parsed_var = 0 ;this is check if arg in <edx,dx,dh,dl,EDX,DX,DH,DL,Edx,Dx,Dh,Dl> display 'Error in ','invoke ',`function, ': ',\ 'you should not use EDX for argument' end if push arg end if end if common call [function] } But in some case it will possible (use edx,part of edx) - need to create more complex macro. to dead_body: i had understand you! It was my bug. I forgot it. To do nested calls you should define this macros several times as level of nesting + 1, like: macro invoke ..... {....} macro invoke ..... {....} macro invoke ..... {....} ..... macro invoke ..... {....} |
|||
08 Aug 2007, 07:59 |
|
dead_body 09 Aug 2007, 19:12
Quote:
official invoke define it automaticly. Maybe you will do it like in official? Some people to lazy to define stack of macroses.. |
|||
09 Aug 2007, 19:12 |
|
Blid 09 Aug 2007, 19:38
to dead_body:
I am lazy too! As for me it simple copy one time and past 3-5 times. And i too lazy think about macro for nesting. I had finish of new version. New modification at the end. |
|||
09 Aug 2007, 19:38 |
|
Blid 09 Aug 2007, 19:41
Code: ;----------=#COMMENTS about INVOKE#=-------------------------- ;invoke GetTickCount,[szbuffer] ;use "dw [hwnddlg]" and any from: dword,Dword,DWORD,dw,d,D,DW,Dw ;will be: ;push DWORD PTR SS:[EBP-1C] ;call [GetTickCount] ;------------------------------------------------------------ ;invoke GetTickCount,addr szbuffer ;use "addr [hwnddlg]" or any from: addr,Addr,ADDR ;this like at standart kit: ;LEA EDX,DWORD PTR SS:[EBP+8] ;PUSH EDX ;call [GetTickCount] ;------------------------------------------------------------ ;invoke GetTickCount,word [mytime.wMinute] ;use "word [mytime.wMinute]" or any from: word,Word,WORD,w,W ;will: ;XOR EDX,EDX ;LEA DX,WORD PTR SS:[EBP+8] ;PUSH EDX ;call [GetTickCount] ;------------------------------------------------------------ ;next ;invoke GetTickCount,word [mytime.wMinute],word [mytime.wHour] ;will: ;XOR EDX,EDX ;LEA DX,WORD PTR SS:[EBP+C] ;PUSH EDX ;LEA DX,WORD PTR SS:[EBP+8] ; (!)no xor edx,edx; mov dx,var = only one xor ;PUSH EDX ;call [GetTickCount] ;------------------------------------------------------------ ;next ;invoke GetTickCount,byte [mytime.wMinute],word [mytime.wHour] ;will: ;xor edx,edx ;mov dx,word [mytime.wHour] ;push edx ;xor edx,edx ;! xor need ;mov dl,byte [mytime.wMinute] ;push edx ;call [GetTickCount] ;------------------------------------------------------------ ;next ;invoke GetTickCount,word [mytime.wMinute],byte [mytime.wHour] ;will: ;xor edx,edx ;mov dl,byte [mytime.wHour] ;push edx ;mov dx,word [mytime.wMinute] ;! xor edx,edx not need ;push edx ;call [GetTickCount] ;------------------------------------------------------------ ;next (this trick was in standart kit): ;invoke GetTickCount,<invoke GetTickCount,[szbuffer]> ;to allow number of nested levels you should define ;this macro number+1 times ;will: ;push dword [szbuffer] ;call [GetTickCount] ;push eax ;call [GetTickCount] ;------------------------------------------------------------ ;next ;if you are use edx for argument: ;invoke DialogBoxParam,edx ;all ok ;invoke DialogBoxParam,edx,NULL ;all ok ;invoke DialogBoxParam,edx,byte [mytime.wMinute]; you will get warning ;(edx uses for push arg) ;invoke DialogBoxParam,byte [mytime.wMinute],edx; edx will be pushed ;first and you do not get warning. ;------------------------------------------------------------ ;strings : ;allowing syntax: ;invoke DialogBoxParam,'Macro not work ()',eax ;and ;invoke DialogBoxParam,<'Macro not work ()'>,eax ;and ;invoke DialogBoxParam,<mystring 'Macro not work ()'>,eax ;define string 'Macro not work ()' with label mystring ;after you can: ;mov eax,mystring and it will be valid ;lable my string is local, it do not change global=you can define ;string in procedure=in this case it will be avaible too ;but you should use this label only after definition=do not get 'undef. sysmb' ;macro: ;macro invoke.create_sizeof name ;defining macro sizeof. ;{ ; sizeof.#name = $-name-1 ;} ;allow you mov eax,sizeof.mystring ;it will be walid ;------------------------------------------------------------ ;code: ;invoke DialogBoxParam,sizeof.s,<s 'Macro not work ()'> ;and: :invoke DialogBoxParam,<s 'Macro not work ()'>,sizeof.s ;are valid! ;------------------------------------------------------------ ;at last you do not need include extended headers ;------------------------------------------------------------ ;do not forget define: macro replace [arg1,arg2] { ;useful: ;replace arg1,arg2,arg3, ;will: ;arg1 equ arg2 ;arg3 equ forward arg1 equ arg2 common } and macro invoke.create_sizeof name ;defining sizeof. { sizeof.#name = $-name-1 } ;before macro invoke defined ;all tested at version : 1.67.21 ;------------------------------------------------------------ ;now i had finished . waiting bug,marks (0-100%) comments . . . . . Code: macro invoke function*,[arg] { common local parsed_var,edx_zero,argument_edx,\ ;local var's ' argument_number,argument_with_edx argument_with_edx=0 ;we do not know number, it is set to 0 edx_zero = 0 ;edx_zero flag, edx is no zero, it is set to 0 argument_edx=0 ;before parsing we do not now it ;find arg edx reverse argument_with_edx = argument_with_edx + 1 ;if last argument->disable: any manipulation cannot ;change this argument if (arg in <edx,dx,dh,dl,EDX,DX,DH,DL,Edx,Dx,Dh,Dl>)&\ (argument_with_edx<>1) argument_edx=1 end if common reverse if ~arg eq parsed_var = 0 ;parsed_var flag, if begin parsing = 0 if arg eqtype '' ;if arg string parsed_var = 1 ;arg parsed as string local ..to_jmp,..metka ;labels for label and jmp jmp ..to_jmp ;jmp over string ..metka db arg,0 ;define string ..to_jmp: push ..metka ;pushing pointer to string end if if arg eqtype [ebp+0] ;if argument is smth: [ebp+12] parsed_var = 1 ;arg is parsed push dword arg ;push dword [ebp+12] else match type some,arg ;type contain type of argum., some have not meanig \{ parsed_var = 1 ;if we here arg is parsed -> set flag if some eqtype '' ;if arg string local ..to_jmp,..metka ;as above jmp ..to_jmp type equ ..metka ..metka: db some,0 ;string with label ..to_jmp: invoke.create_sizeof type push ..metka ;pushing pointer to string end if if type in <addr,Addr,ADDR,> ;if arg: 'Addr ebp+12' (LocalVar1) if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if replace addr, ,Addr, ,ADDR ;erase ADDR from arg,using dir 'equ' lea edx,[arg] ;loading adress edx_zero =0 ;now edx is no zero, flag to 0 restore addr,Addr,ADDR ;restoring addr,... push edx end if if type in <b,B,byte,BYTE,Byte> ;if byte load it to edx and push if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if replace b, ,byte, ,BYTE, ,Byte, if edx_zero <= 2 ;is need to clear edx? xor edx,edx ;clear edx end if mov dl,arg edx_zero = 3 ;the part of regis is not clean,set flag restore b,byte,BYTE,Byte push edx end if if type in <word,Word,WORD,w,W> ;such as for byte if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if replace w,Word,W,Word if edx_zero = 0 xor edx,edx end if mov dx,arg dx_zero = 2 push edx restore w,W end if if type in <dword,Dword,DWORD,dw,d,D,DW,Dw> ;such as for byte, but not using edx replace d,dword,dw,dword,D,dword,DW,dword,Dw,dword push arg restore d,D,dw,DW,Dw end if if type eq invoke ;is this nested invoke -> parse if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if arg push eax ;push return value edx_zero =0 ;after invoke edx is not clean -> set flag end if \} if parsed_var = 0 ;if var is not parsed -> push it push arg end if end if end if common call [function] ;at last indirect call } |
|||
09 Aug 2007, 19:41 |
|
Blid 17 Aug 2007, 09:02
Code: ;the latest version of macro, correct minor bugs, no need replace ;macro, only macro for sizeof like above. ;You will found cinvoke too. ;write comments and you marks ;In other case i would think what you do not need this and finish to share ;macro . macro invoke function*,[arg] { ;warning not allowed: ByTe,WoRd common local parsed_var,edx_status,argument_edx,\ ;local var's ' argument_number,argument_with_edx argument_with_edx=0 ;we do not know number, it is set to 0 edx_status = 0 ;edx_status flag, edx is no zero, it is set to 0 ;edx contain smth == 0 ;edx is clean, but dx is not == 1 ;edx and dx is clean, but dl is not == 2 ;edx is clear == 3 argument_edx=0 ;before parsing we do not now it ;find arg edx reverse argument_with_edx = argument_with_edx + 1 ;if last argument->disable: any manipulation cannot ;change this argument if (arg in <edx,dx,dh,dl,EDX,DX,DH,DL,Edx,Dx,Dh,Dl>)&(argument_with_edx<>1) argument_edx=1 end if common reverse if ~arg eq parsed_var = 0 ;parsed_var flag, if begin parsing = 0 ;case string if arg eqtype '' ;if arg string parsed_var = 1 ;arg parsed as string local ..to_jmp,..metka ;labels for label and jmp jmp ..to_jmp ;jmp over string ..metka db arg,0 ;define string ..to_jmp: push ..metka ;pushing pointer to string end if ;case register based if arg eqtype [ebp+0] ;if argument is smth: [ebp+12] parsed_var = 1 ;arg is parsed push dword arg ;push dword [ebp+12] else match type some,arg ;type contain type of argum., some have not meanig \{ parsed_var = 1 ;if we here arg is parsed -> set flag ;case string with label if some eqtype '' ;if arg string local ..to_jmp,..metka ;as above jmp ..to_jmp type equ ..metka ..metka: db some,0 ;string with label ..to_jmp: invoke.create_sizeof type push ..metka ;pushing pointer to string end if ;case type byte if type in <b,B,byte,BYTE,Byte> ;if byte load it to edx and push if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if if edx_status < 2 ;is need to clear edx? xor edx,edx ;clear edx end if mov dl,ByTe some edx_status = 2 ;the part of register is not clean,set flag push edx restore b,B,byte,BYTE,Byte end if ;case type addr if type in <Addr,addr,ADDR> ;if arg: 'Addr ebp+12' (LocalVar1) if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if lea edx,[some] ;loading adress push edx edx_status =0 ;now edx is no zero, flag to 0 restore Addr,addr,ADDR end if ;case type word if type in <word,Word,WORD,w,W> ;such as for byte if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if if edx_status = 0 xor edx,edx end if mov dx,WoRd some edx_status = 1 push edx restore word,Word,WORD,w,W end if ;case type dword if type in <dword,Dword,DWORD,dw,d,D,DW,Dw> ;such as for byte, but not using edx push arg end if ;case type invoke if type eq invoke ;is this nested invoke -> parse if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if arg push eax ;push return value edx_status =0 ;after invoke edx is not clean -> set flag end if \} ;case type none if parsed_var = 0 ;if var is not parsed -> push it push arg end if end if end if common call [function] ;at last indirect call } macro cinvoke function*,[arg] { ;warning not allowed: ByTe,WoRd common local parsed_var,edx_status,argument_edx,\ ;local var's ' argument_number,argument_with_edx,\ param_cntr param_cntr=0 ;count parametrs argument_with_edx=0 ;we do not know number, it is set to 0 edx_status = 0 ;edx_status flag, edx is no zero, it is set to 0 ;edx contain smth == 0 ;edx is clean, but dx is not == 1 ;edx and dx is clean, but dl is not == 2 ;edx is clear == 3 argument_edx=0 ;before parsing we do not now it reverse if ~arg eq param_cntr = param_cntr + 1 end if common ;find arg edx reverse argument_with_edx = argument_with_edx + 1 ;if last argument->disable: any manipulation cannot ;change this argument if (arg in <edx,dx,dh,dl,EDX,DX,DH,DL,Edx,Dx,Dh,Dl>)&(argument_with_edx<>1) argument_edx=1 end if common reverse if ~arg eq parsed_var = 0 ;parsed_var flag, if begin parsing = 0 ;case string if arg eqtype '' ;if arg string parsed_var = 1 ;arg parsed as string local ..to_jmp,..metka ;labels for label and jmp jmp ..to_jmp ;jmp over string ..metka db arg,0 ;define string ..to_jmp: push ..metka ;pushing pointer to string end if ;case register based if arg eqtype [ebp+0] ;if argument is smth: [ebp+12] parsed_var = 1 ;arg is parsed push dword arg ;push dword [ebp+12] else match type some,arg ;type contain type of argum., some have not meanig \{ parsed_var = 1 ;if we here arg is parsed -> set flag ;case string with label if some eqtype '' ;if arg string local ..to_jmp,..metka ;as above jmp ..to_jmp type equ ..metka ..metka: db some,0 ;string with label ..to_jmp: invoke.create_sizeof type push ..metka ;pushing pointer to string end if ;case type byte if type in <b,B,byte,BYTE,Byte> ;if byte load it to edx and push if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if if edx_status < 2 ;is need to clear edx? xor edx,edx ;clear edx end if mov dl,ByTe some edx_status = 2 ;the part of register is not clean,set flag push edx restore b,B,byte,BYTE,Byte end if ;case type addr if type in <Addr,addr,ADDR> ;if arg: 'Addr ebp+12' (LocalVar1) if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if lea edx,[some] ;loading adress push edx edx_status =0 ;now edx is no zero, flag to 0 restore Addr,addr,ADDR end if ;case type word if type in <word,Word,WORD,w,W> ;such as for byte if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if if edx_status = 0 xor edx,edx end if mov dx,WoRd some edx_status = 1 push edx restore word,Word,WORD,w,W end if ;case type dword if type in <dword,Dword,DWORD,dw,d,D,DW,Dw> ;such as for byte, but not using edx push arg end if ;case type invoke if type eq invoke ;is this nested invoke -> parse if argument_edx=1 ;if argument cont. edx -> warning err you should not use EDX for argument end if arg push eax ;push return value edx_status =0 ;after invoke edx is not clean -> set flag end if \} ;case type none if parsed_var = 0 ;if var is not parsed -> push it push arg end if end if end if common call [function] ;at last indirect call if param_cntr > 0 if param_cntr = 2 pop edx pop edx end if if param_cntr = 1 pop edx end if if param_cntr > 2 add esp,param_cntr*4 end if end if } |
|||
17 Aug 2007, 09:02 |
|
Goto page 1, 2 Next < Last Thread | Next Thread > |
Forum Rules:
|
Copyright © 1999-2024, Tomasz Grysztar. Also on GitHub, YouTube.
Website powered by rwasa.