flat assembler
Message board for the users of flat assembler.

Index > Windows > Can't understand STDCALL.INC macro

Author
Thread Post new topic Reply to topic
milind



Joined: 15 Feb 2004
Posts: 33
milind 29 Mar 2004, 21:27
Hello,
I am new to Win32 programming in Assembly. I found some FASM tutorials written analogous to Iczelion's Win32 ASM tutorials. I was studying them, but I simply cannot understand the macro proc in the stdcall.inc file. The code is pasted below

Code:

macro proc name,[arg]                   ; define procedure
 { common
    name:
    virtual at ebp+8
    if ~ arg eq
   forward
     local ..arg
     ..arg dd ?
     arg equ ..arg
   common
     end if
     ..ret = $ - (ebp+8)
    end virtual
    local ..dynamic_data,..dynamic_size
    dynamic_data equ ..dynamic_data
    dynamic_size equ ..dynamic_size
    virtual at ebp - dynamic_size
     dynamic_data: }

macro enter                             ; begin procedure instructions
 { dynamic_size = $ - dynamic_data
   end virtual
   enter dynamic_size,0 }

macro return                            ; return from procedure
 { leave
   ret ..ret }

macro stdcall proc,[arg]                ; call procedure
 { reverse
    push arg
   common
    call proc }

macro invoke proc,[arg]                 ; invoke procedure (indirect)
 { common
    if ~ arg eq
     stdcall [proc],arg
    else
     call [proc]
    end if }          

    


Now this is used as follows in tutorial 3:

Code:
        ......
        ......
        stdcall WinMain, [hInstance],NULL, [CommandLine],SW_SHOWDEFAULT 
       invoke  ExitProcess, eax

  proc WinMain, hInst,hPrevInst,CmdLine,CmdShow
[code]    wc WNDCLASSEX
    msg MSG
    hwnd dd ?[/code]        enter                        
         .....
         .....


    


The first thing I don't understand is why is 8 added to EBP in the macro proc, when the lexical nesting level of the ENTER opcode is 0. For 0 EBP is pushed and then ESP is copied to the EBP and then the dynamic storage is allocated. So the dynamic storage is only +4 bytes from the value of EBP isn't it, so why is 8 added?
The next thing is related to the $ sign, I am confused as to what offset does it give. I used to thing it would give the offsets of the assembled object file thats why when we make a bootloader we can use the statement :

Code:

times 510-($-main) db 0   ; Fill the rest with zeros

    


But here the $ is used to calculate the number of bytes in the virtual declaration. How can it give that? Actually I don't understand that part at all, please can anybody explain it to me, it would be a great help.
Another confusing thing to me is that after the procedure heading there are 3 local variables declared i.e.:

Code:
    wc WNDCLASSEX
    msg MSG
    hwnd dd ?
    

But in the proc macro the procedure name is made as a label right in the beginning. So when this procedure is called it will jump to that label and find those declarations there, so how will it skip them and reach the executable statements.
Also the virtual block declares the parameters using the forward block, shouldn't it be the revese block since the 1st parameter is at EBP+4 (supposedly) so in a reverse block the addressing will match. I know I am all messed up, please sort this out anybody.
Post 29 Mar 2004, 21:27
View user's profile Send private message Visit poster's website Yahoo Messenger Reply with quote
Tomasz Grysztar



Joined: 16 Jun 2003
Posts: 8358
Location: Kraków, Poland
Tomasz Grysztar 29 Mar 2004, 21:46
The 8 that is added to EBP is the return address of procedure and the backup of previous EBP value that is always stored on the stack after (that is: below) the parameters.

$ always gives a value of the address at which the current place in code is assumed to occur in memory. You can set this value with the "org" directive (you can even write "$=100h" instead of "org 100h".
The special case is the "virtual" directive. This directive marks the temporary code that will not be generated into output file, and you specify address at which it would be supposed to occur in memory. For example:
Code:
virtual at ebx
  var1 dd ?
  var2 dd ?
end virtual    

defines a variable at address "ebx+4", so if you use "mov eax,[var2]" instruction, it will be assembled into "mov eax,[ebx+4]".
The "proc" macro starts the virtual block at the appropriate EBP-based address, end this block is ended by the "enter" macro. That's why variables that you put between the "proc" and "enter" won't be actually placed in the code, but they are defined as a local variables with EBP-based addresses.
For few more details on using the "virtual", etc. you can look also in manual.
Post 29 Mar 2004, 21:46
View user's profile Send private message Visit poster's website Reply with quote
milind



Joined: 15 Feb 2004
Posts: 33
milind 29 Mar 2004, 22:01
Thanks a lot Privalov it cleared all my doubts. Just one confusion remains. Does this mean that if we declare virtual blocks in our code we will not get the offset as it would be in the output file with the '$' operator. Please clarify.
Thanks for the quick reply.
Post 29 Mar 2004, 22:01
View user's profile Send private message Visit poster's website Yahoo Messenger 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


Copyright © 1999-2025, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.