flat assembler
Message board for the users of flat assembler.

Index > Windows > Iczelion's Win32 ASM tutorial (NEWBIE)

Author
Thread Post new topic Reply to topic
edorix



Joined: 20 Apr 2007
Posts: 5
edorix 20 Apr 2007, 20:06
I am really in need of help. I am trying to learn win32 API in Fasm but I'm having some primary problems.

1) Is there no HINSTANCE structure?
2) Further more what about LPSTR

Actually I was working from a tutorial and when I got to chapter 3 I began to have serious problems.

http://win32assembly.online.fr/tut3.html

I'm hoping someone will be able to tell me what I need to do to that code to get it to work in Fasm. I know the basic stuff, like not having .386, and about data import and such, its just when it comes to LOCAL and things like that, I don't really know what to do. Thanks in advanced for any help you may give me. Thanks.
Shawn

P.S. I have read the FASM manual cover to cover.
Post 20 Apr 2007, 20:06
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Apr 2007, 20:41
Both, HINSTANCE and LPSTR are double words. If you want to declare variables of such types is enough to to this
Code:
hInstance dd ?
lpString dd ?    

If you what a local variable you have to use the "local" macro. You can learn about it here. In this case is "local hInstance: DWORD, lpString: DWORD".
Post 20 Apr 2007, 20:41
View user's profile Send private message Reply with quote
edorix



Joined: 20 Apr 2007
Posts: 5
edorix 20 Apr 2007, 20:49
Thanks LocoDelAssembly. Another problem that I have been having that I should have mentioned in my initial post is I get the following error:

Error Invalid Operand

When I try to do

mov hInstance,eax

Here is my full code.

Code:
include "win32ax.inc"

.code

start:
        invoke  GetModuleHandle,NULL

        mov     hInstance,eax
        invoke  GetCommandLine

        mov     CommandLine,eax
        invoke  WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT
        invoke  ExitProcess,eax

proc    WinMain,hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD

endp


.data
        ClassName       db      "SimpleWinClass",0
        AppName         db      "Our first Window",0
        hInstance       dd      ?
        CommandLine     dd      ?

data import
     library kernel32, 'KERNEL32.DLL',\
             user32, 'USER32.DLL'
     include 'api\kernel32.inc'
     include 'api\user32.inc'
end data
    
Post 20 Apr 2007, 20:49
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Apr 2007, 20:55
Every time you need to access memory, the source/destination memory operand should be enclosed in square brackets. Another difference with MASM is that there is no OFFSET specifier, but fasm stills support it, you have to just provide the label name and that's all.

Code:
  mov eax, varA ; EAX <- varA's offset
  mov eax, [varA] ; EAX <- varA's content    


[edit]Note also that
Code:
invoke  WinMain,hInstance,NULL,CommandLine,SW_SHOWDEFAULT    
should be
Code:
invoke  WinMain,[hInstance],NULL,[CommandLine],SW_SHOWDEFAULT    
Since you are interested in passing the contents of those vars to WinMain and not its offsets[/edit]
Post 20 Apr 2007, 20:55
View user's profile Send private message Reply with quote
edorix



Joined: 20 Apr 2007
Posts: 5
edorix 20 Apr 2007, 21:08
Thanks again, unfortunately I am having even more problems. I still can't get

mov hInstance,eax

to work and

mov hInstance,[eax]

doesn't work either. This becomes even more of a problem later when attempting the following:

Code:
proc    WinMain,hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
        local wc:WNDCLASSEX,msg:MSG,hwnd:DWORD

        mov     wc.cbSize,SIZEOF WNDCLASSEX
        mov     wc.style,CS_HREDRAW or CS_VREDRAW
        mov     wc.lpfnWndProc,offset WndProc
        mov     wc.cbClsExtra,NULL
        mov     wc.cbWndExtra,NULL
        push    hInstance
        pop     wc.hInstance
        mov     wc.hbrBackground,COLOR_WINDOW+1
        mov     wc.lpszMenuName,NULL
        mov     wc.lpszClassName,<OFFSET ClassName>
        invoke  LoadIcon,NULL,IDI_APPLICATION
        mov     wc.hIcon,eax
    


I noticed some primary problems. For one there appears to not be a sizeof operator. Second I can't move data into any of these it always gives the same error. Invalid operator. Also, what can I use as an alternative to or? Sorry to bother you again but I've tried quite a few different things and none of them are seeming to work. Thanks again.
Shawn
Post 20 Apr 2007, 21:08
View user's profile Send private message Reply with quote
edorix



Joined: 20 Apr 2007
Posts: 5
edorix 20 Apr 2007, 21:22
Actually there may be even more errors with my code. What I have is almost a verbatim copy of what is in the tutorial with everything I know how to change changed. Here it is.

Code:
include "win32ax.inc"

.code

start:
        invoke  GetModuleHandle,NULL

        mov     hInstance,eax
        invoke  GetCommandLine

        mov     CommandLine,eax
        invoke  WinMain,[hInstance],NULL,[CommandLine],SW_SHOWDEFAULT
        invoke  ExitProcess,eax

proc    WinMain,hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD
        local wc:WNDCLASSEX,msg:MSG,hwnd:DWORD

        mov     wc.cbSize,SIZEOF WNDCLASSEX
        mov     wc.style,CS_HREDRAW or CS_VREDRAW
        mov     wc.lpfnWndProc,WndProc
        mov     wc.cbClsExtra,NULL
        mov     wc.cbWndExtra,NULL
        push    hInstance
        pop     wc.hInstance
        mov     wc.hbrBackground,COLOR_WINDOW+1
        mov     wc.lpszMenuName,NULL
        mov     wc.lpszClassName,ClassName
        invoke  LoadIcon,NULL,IDI_APPLICATION
        mov     wc.hIcon,eax
        mov     wc.hIconSm,eax
        invoke  LoadCursor,NULL,IDC_ARROW
        mov     wc.hCursor,eax
        invoke  RegisterClassEx,addr wc
        invoke  CreateWindowEx,NULL,\
                addr ClassName,\
                addr AppName,\
                WS_OVERLAPPEDWINDOW,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                CW_USEDEFAULT,\
                NULL,\
                NULL,\
                hInst,\
                NULL

        mov     hwnd,eax
        invoke  ShowWindow,[hwnd],CmdShow
        invoke  UpdateWindow,[hwnd]

        .while TRUE
               invoke   GetMessage,addr msg,NULL,0,0
               .break .if(!eax)
               invoke TranslateMessage,addr msg
               invoke DispatchMessage,addr msg
        .endw

        mov     eax,msg.wParam
        ret
endp

proc    WndProc,hWnd:DWORD,uMsg:UINT,wParam:WPARAM,lParam:LPARAM
        .if uMsg==WM_DESTROY
            invoke      PostQuitMessage,NULL
        .else
            invoke      DefWindowProc,[hWnd],[uMsg],[wParam],[lParam]
            ret
        .endif
        xor     eax,eax
        ret
endp



.data
        ClassName       db      "SimpleWinClass",0
        AppName         db      "Our first Window",0
        hInstance       dd      ?
        CommandLine     dd      ?

data import
     library kernel32, 'KERNEL32.DLL',\
             user32, 'USER32.DLL'
     include 'api\kernel32.inc'
     include 'api\user32.inc'
end data
    


Thanks again, especially if you actually went through that and picked out the things I did wrong.
Shawn
Post 20 Apr 2007, 21:22
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 20 Apr 2007, 23:55
Code:
include "win32ax.inc"

.code  

start:  
        invoke  GetModuleHandle,NULL  

        mov     [hInstance],eax  
        invoke  GetCommandLine  

        mov     [CommandLine],eax  
        stdcall WinMain,[hInstance],NULL,[CommandLine],SW_SHOWDEFAULT
        invoke  ExitProcess,eax  

proc    WinMain,hInst:DWORD,hPrevInst:DWORD,CmdLine:DWORD,CmdShow:DWORD  
        local wc:WNDCLASSEX,msg:MSG,hwnd:DWORD  

        mov     [wc.cbSize], sizeof.WNDCLASSEX
        mov     [wc.style],CS_HREDRAW or CS_VREDRAW  
        mov     [wc.lpfnWndProc],WndProc  
        mov     [wc.cbClsExtra],NULL  
        mov     [wc.cbWndExtra],NULL  
        push    [hInstance]  
        pop     [wc.hInstance]  
        mov     [wc.hbrBackground],COLOR_WINDOW+1  
        mov     [wc.lpszMenuName],NULL  
        mov     [wc.lpszClassName],ClassName  
        invoke  LoadIcon,NULL,IDI_APPLICATION  
        mov     [wc.hIcon],eax  
        mov     [wc.hIconSm],eax  
        invoke  LoadCursor,NULL,IDC_ARROW  
        mov     [wc.hCursor],eax  
        invoke  RegisterClassEx,addr wc  
        invoke  CreateWindowEx,NULL,\  
                ClassName,\  
                AppName,\  
                WS_OVERLAPPEDWINDOW,\  
                CW_USEDEFAULT,\  
                CW_USEDEFAULT,\  
                CW_USEDEFAULT,\  
                CW_USEDEFAULT,\  
                NULL,\  
                NULL,\  
                [hInst],\  
                NULL  

        mov     [hwnd],eax  
        invoke  ShowWindow,[hwnd],[CmdShow]  
        invoke  UpdateWindow,[hwnd]  

        .while TRUE  
               invoke   GetMessage,addr msg,NULL,0,0  
               .if (~eax)
                  jmp .exitWhile
               .endif
               invoke TranslateMessage,addr msg  
               invoke DispatchMessage,addr msg  
        .endw  
        .exitWhile:
        mov     eax,[msg.wParam] 
        ret  
endp  

proc    WndProc,hWnd:DWORD,uMsg:DWORD,wParam:DWORD,lParam:DWORD
        .if [uMsg]=WM_DESTROY
            invoke      PostQuitMessage,NULL  
        .else  
            invoke      DefWindowProc,[hWnd],[uMsg],[wParam],[lParam]  
            ret  
        .endif  
        xor     eax,eax  
        ret  
endp  



.data  
        ClassName       db      "SimpleWinClass",0  
        AppName         db      "Our first Window",0  
        hInstance       dd      ?  
        CommandLine     dd      ?  

.end start    


Using "addr" for parameters is only needed when you need to provide a pointer to local data (data located at stack frame), otherwise is unneded and I recommend to not use it because for every parameter with "addr" the following code gets assembled
Code:
lea edx, [parameter]
push edx    
There is no problem with that sequence when you use global data but is less efficient than a simple "push parameter".
Post 20 Apr 2007, 23:55
View user's profile Send private message Reply with quote
LocoDelAssembly
Your code has a bug


Joined: 06 May 2005
Posts: 4624
Location: Argentina
LocoDelAssembly 21 Apr 2007, 01:20
Sorry, when I replyed I was on Linux and I couldn't test what I posted. I have corrected some syntax errors in my post above, now compiles and works fine.
Post 21 Apr 2007, 01:20
View user's profile Send private message Reply with quote
kohlrak



Joined: 21 Jul 2006
Posts: 1421
Location: Uncle Sam's Pad
kohlrak 22 Apr 2007, 12:37
If you have any more trouble, i am working on learning it, as well, so i have saved alot of my source code. Also, i think SleepSleep or some one else here has a website that has fasm equivalents to Iczelion's tuts, which i've been using as a cross referance.
Post 22 Apr 2007, 12:37
View user's profile Send private message Visit poster's website AIM Address Yahoo Messenger MSN 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-2024, Tomasz Grysztar. Also on GitHub, YouTube.

Website powered by rwasa.