flat assembler
Message board for the users of flat assembler.
 Home   FAQ   Search   Register 
 Profile   Log in to check your private messages   Log in 
flat assembler > Main > Problem creating a wrapper with "macro" instructio

Author
Thread Post new topic Reply to topic
Sasha



Joined: 17 Nov 2011
Posts: 93
Problem creating a wrapper with "macro" instructio
Can you please explain why this happens and how to do it the right way?
Yes, I would like to define the same names for macroses and for procs. But if it's not possible..

Code:

include 'win32ax.inc'

macro   Error Msg
{
        stdcall Error,Msg
}

macro   Alert Msg
{
        stdcall _Alert,Msg
}

macro GetCmd
{
        invoke GetCommandLine
}

macro GetCommandLine
{
        invoke GetCommandLine
}

.code

  start:
        GetCommandLine
        invoke  MessageBox,HWND_DESKTOP,"Hello World!",eax,MB_OK                        ;Works                   
        invoke  MessageBox,HWND_DESKTOP,"Hello World!",invoke GetCommandLine,MB_OK      ;Works
        invoke  MessageBox,HWND_DESKTOP,"Hello World!",GetCommandLine,MB_OK             ;Doesn't Work. Why? It's almost the same like a previous one
        invoke  MessageBox,HWND_DESKTOP,"Hello World!",GetCmd,MB_OK                     ;Doesn't Work  Error: Undefined Symbol 'GetCmd'. Instruction: push GetCmd. Even this way.
        Alert   "Information Message"                                                   ;Works
        Error   "Error Message"                                                         ;Doesn't Work. But when we define a macros with the same name as imported function it works, so wat's the problem?

        invoke  ExitProcess,0

proc    Error Msg

        invoke  MessageBox,HWND_DESKTOP,[Msg],NULL,MB_OK+MB_ICONERROR
        ret
endp                                                                                    ;Error: unexpected instruction. Instruction: end if

proc    _Alert Msg

        invoke  MessageBox,HWND_DESKTOP,[Msg],"Information",MB_OK+MB_ICONINFORMATION
        ret
endp

.end start


Post 11 Oct 2013, 18:58
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
fasm does not support inline macros. The parser does not do macro substitution within argument parameters. 'GetCmd' is not substituted unless you define it with equ or fix.
Post 12 Oct 2013, 01:12
View user's profile Send private message Visit poster's website Reply with quote
Sasha



Joined: 17 Nov 2011
Posts: 93
But 'invoke' is a macroinstruction. How does it work?
Post 12 Oct 2013, 01:20
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
The invoke macro has special support for nested invoke's inside of it. This does not extend to just any random macro instruction unless you specifically alter the invoke macro code to detect them.
Post 12 Oct 2013, 02:14
View user's profile Send private message Visit poster's website Reply with quote
Sasha



Joined: 17 Nov 2011
Posts: 93
And what about 'unexpected instruction' error? I can define a macro with the same name as imported function, but I can not define a macro with the same name as my own function. Is the solution in exporting my functions to dll?
Post 12 Oct 2013, 10:23
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
If we look at the proc macro we see how it will try to define the procedure name:

Code:
if used Error
Error;expanded to ---> stdcall Error,:
;...
end if

Because the name 'Error' is a macro we find the proc cannot now define a label name because the macro takes precedence.

Note that if the macro is defined after the label name then it will compile:

Code:
if used Error
Error;defines the label name
end if
macro Error Msg {stdcall Error,Msg}
Error   "Error Message"

Post 12 Oct 2013, 11:38
View user's profile Send private message Visit poster's website Reply with quote
Sasha



Joined: 17 Nov 2011
Posts: 93
In other words, I need to define macroses after the procedures. But procedures are defined in the code segment and are used in the code segment. So the macroses have to be defined in the code segment, too. But it is not the common way! Generally, the macroses are defined at the begining of the source file. So what's the solution? Modify the 'proc' macro to remove this check?
Post 12 Oct 2013, 14:34
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
Perhaps you can try using the label directive in the proc macro:

Code:
;...
if used name
label name ;try with this instead of 'name:'
;.,.

Post 12 Oct 2013, 14:51
View user's profile Send private message Visit poster's website Reply with quote
Sasha



Joined: 17 Nov 2011
Posts: 93
Thanks, it seems working on this example. I'm going to test it on my project.
Post 13 Oct 2013, 10:24
View user's profile Send private message Reply with quote
Sasha



Joined: 17 Nov 2011
Posts: 93
You've seen, that defining a macro with the same name as imported function, works. Look at 'GetCommandLine'.
But there is something wrong with ExitProcess. Using standard headers or modified gives the same result.

Code:

include 'win32ax.inc'

macro   ExitProcess ExitCode{invoke  ExitProcess,ExitCode}

.code

  start:
        ExitProcess 0

.end start       ;<<Error: Invalid operand. Instruction: push dd RVA _label?Uj




Defining ExitProcess without an exitcode operand leads to this:

Code:

include 'win32ax.inc'

macro   ExitProcess{invoke  ExitProcess,0}

.code

  start:
        ExitProcess

.end start       ;<<Error: Invalid macro arguments    


Post 13 Oct 2013, 15:12
View user's profile Send private message Reply with quote
revolution
When all else fails, read the source


Joined: 24 Aug 2004
Posts: 15237
Location: 1I/ʻOumuamua
This occurs for all APIs. Look at the IMPORT32.INC file and you see this:

Code:
       label dd RVA _label

'label' is replaced by ExitProcess and the parser does this:

Code:
ExitProcess dd RVA _label

And then expands the macro to:

Code:
invoke  ExitProcess,dd RVA _label

Post 13 Oct 2013, 15:38
View user's profile Send private message Visit poster's website Reply with quote
Display posts from previous:
Post new topic Reply to topic

Jump to:  


< Last Thread | Next Thread >

Forum Rules:
You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum
You cannot vote in polls in this forum
You cannot attach files in this forum
You can download files in this forum


Powered by phpBB © 2001-2005 phpBB Group.

Main index   Download   Documentation   Examples   Message board
Copyright © 2004-2016, Tomasz Grysztar.