A Simple Window in FASM

I made a freakin empty window in fasm assembly. My source code is actually complicated since I like to directly place parameters on the stack and control memory allocation, so if you want a simpler code with similar results, I suggest you see the FASM32\EXAMPLES\TEMPLATE example. So here’s my code:

format PE GUI 4.0
entry main
include 'macro\import32.inc'
include 'macro\struct.inc'
include 'macro\proc32.inc'

section '.text' code readable executable

main:
push ebp
mov ebp,esp                            ;Set up stack frame
sub esp,56                             ;Allocate 56 bytes on stack
mov dword [esp],0
call [GetModuleHandle]                 ;Get handle to module that called this process
sub esp,4                              ;Rebalance stack after call
mov [wc.hInstance],eax                 ;Store retrieved handle in wc.hInstance
mov dword [esp],0                      ;Handle to module containing icon (null for sys icon)
mov dword [esp+4],32514                ;Question Mark icon constant
call [LoadIcon]
sub esp,8                              ;Rebalance stack after call
mov [wc.hIcon],eax                     ;Store retrieved icon ptr into wc.hIcon
mov dword [esp],0                      ;Handle to module containing cursor (null for sys cursor)
mov dword [esp+4],32512                ;Regular arrow cursor constant
call [LoadCursor]
sub esp,8                              ;Rebalance stack after call
mov [wc.hCursor],eax                   ;Store retrieved cursor ptr to wc.hCursor
mov eax,wc
mov dword [esp],eax
call [RegisterClass]                   ;Register our wndclass
sub esp,4                              ;Rebalance stack after call
test eax,eax                           ;Did it fail (if ((eax&eax)==0))
jz Die                                 ;Exit if fails
mov dword [esp],0                      ;Extended Window Style
mov dword [esp+4],_class               ;Registered class name
mov dword [esp+8],_title               ;Window Title
mov dword [esp+12],10080000h           ;Window Style constant for visible+corner button(s)
mov dword [esp+16],128                 ;Horizontal location
mov dword [esp+20],128                 ;Vertical location
mov dword [esp+24],256                 ;Width
mov dword [esp+28],192                 ;Height
mov dword [esp+32],0                   ;Parent Window (NULL)
mov dword [esp+36],0                   ;Parent Menu (NULL)
mov eax,dword [wc.hInstance]           ;Handle to intance of module to be assoc w/ window
mov dword [esp+40],eax
mov dword [esp+44],0                   ;Pointer to args to window
call [CreateWindowEx]                  ;Finally create our window
sub esp,48                             ;Rebalance stack
test eax,eax
jz Die                                 ;Exit if create window failed
Stay_Alive:
mov dword [esp],msg                    ;MSG structure buffer for listening for window msgs
mov dword [esp+4],0                    ;Retrieve message from which window (0=all)
mov dword [esp+8],0                    ;Message must be greater than 0
mov dword [esp+12],0                   ;Message must be at most 0 (>0 && <0 means accept all)
call [GetMessage]
sub esp,16                             ;Rebalance
cmp eax,1                              ;If return 1 then WM_QUIT msg sent
jb Die
jne Stay_Alive
mov dword [esp],msg
call [TranslateMessage]
sub esp,4
mov dword [esp],msg
call [DispatchMessage]
sub esp,4
jmp Stay_Alive
Die:
leave                                  ;Restore stack frame
mov eax,dword [msg.wParam]
mov dword [esp],eax
call [ExitProcess]

proc WindowProc hwnd,wmsg,wparam,lparam
push ebx
push esi
push edi                               ;For some reason, these regs must be saved
sub esp,24                             ;Alloc 24
mov eax,[wmsg]
cmp eax,2                              ;Is message WM_DESTROY? (Termination Request)
je .wmdestroy                          ;If so, go to wmdestroy
mov eax,[hwnd]
mov dword [esp],eax
mov eax,[wmsg]
mov dword [esp+4],eax
mov eax,[wparam]
mov dword [esp+8],eax
mov eax,[lparam]
mov dword [esp+12],eax
call [DefWindowProc]                   ;Otherwise, process arguments with the default
add esp,16                             ;window procedure
jmp .finish
.wmdestroy:
mov dword [esp],0                      ;Return status 0
call [PostQuitMessage]                 ;Respond to WM_DESTROY with an "I'm quitting message"
add esp,4                              ;and then send WM_QUIT to message queue
xor eax,eax
.finish:
add esp,24
pop edi
pop esi
pop ebx                                ;Restore these
ret                                    ;Return
endp

section '.data' data readable writeable

struct WNDCLASS
 style         dd ?
 lpfnWndProc   dd ?
 cbClsExtra    dd ?
 cbWndExtra    dd ?
 hInstance     dd ?
 hIcon         dd ?
 hCursor       dd ?
 hbrBackground dd ?
 lpszMenuName  dd ?
 lpszClassName dd ?
ends

struct POINT
 x dd ?
 y dd ?
ends

struct MSG
 hwnd    dd ?
 message dd ?
 wParam  dd ?
 lParam  dd ?
 time    dd ?
 pt      POINT
ends

_class db "MYWINDOWPROGRAM",0
_title db "Why so serious?",0
wc WNDCLASS 0,WindowProc,0,0,0,0,0,16,0,_class
msg MSG

section '.idata' import data readable writeable
library user,'user32.dll',\
kernel,'kernel32.dll'

import kernel,\
GetModuleHandle,'GetModuleHandleA',\
ExitProcess,'ExitProcess'

import user,\
LoadIcon,'LoadIconA',\
LoadCursor,'LoadCursorA',\
RegisterClass,'RegisterClassA',\
CreateWindowEx,'CreateWindowExA',\
GetMessage,'GetMessageA',\
TranslateMessage,'TranslateMessage',\
DispatchMessage,'DispatchMessageA',\
DefWindowProc,'DefWindowProcA',\
PostQuitMessage,'PostQuitMessage'

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

%d bloggers like this: