Assembly Language Programming

September 30, 2013

FASM – Win32 Hello World

Filed under: Assembly Language, C++ — Tags: , , , — programmer209 @ 1:29 pm

This post shows how to write a Win32 “Hello World” program in x86 assembly language using FASM – the flat assembler.

It is a direct translation of the C language Win32 “Hello World” program that can be found on the MSDN website:

http://msdn.microsoft.com/en-us/library/vstudio/bb384843.aspx

The following steps are required to create and display a basic window:

(1) Fill a WNDCLASSEX structure with information about the window.

(2) Call RegisterClassEx to register the windows class.

(3) Call CreateWindowEx to create the window.

(4) Call ShowWindow and UpdateWindow to show the window.

(5) Create a callback function (WndProc) to process any messages received by the application.

(6) Create a main message loop that will dispatch the messages to the WndProc function.

(7) Inside WndProc, handle the WM_PAINT message to print the "Hello World" greeting.

Related Post

FASM – A Simple Win32 Text Editor

The FASM Code

To grab this code, select with the mouse and then copy and paste directly into the FASM IDE.

; -------------------------------------------------------------------------------------

        ; FASM version of Win32 Hello World:

        ; http://msdn.microsoft.com/en-us/library/vstudio/bb384843.aspx

; -------------------------------------------------------------------------------------

 format PE GUI 4.0

 entry win_main

 include 'win32a.inc'

; -------------------------------------------------------------------------------------

 section '.code' code readable executable

  win_main:

        ; initialise the members of the wcex structure

        ; --------------------------------------------

        ; WNDCLASSEX

        ; UINT cbSize
        ; UINT style
        ; WNDPROC lpfnWndProc
        ; int cbClsExtra
        ; int cbWndExtra
        ; HINSTANCE hInstance
        ; HICON hIcon
        ; HCURSOR hCursor
        ; HBRUSH hbrBackground
        ; LPCTSTR lpszMenuName
        ; LPCTSTR lpszClassName
        ; HICON hIconSm

        ; --------------------------------------------

        ; the instance handle

        invoke GetModuleHandle,0

        mov [wcex.hInstance],eax

        ; cbSize

        mov eax,sizeof.WNDCLASSEX

        mov [wcex.cbSize],eax

        ; the windows proc

        mov [wcex.lpfnWndProc],WndProc

        ; the windows style

        mov [wcex.style],CS_HREDRAW+CS_VREDRAW

        ; load the icons

        invoke LoadIcon,[wcex.hInstance],IDI_APPLICATION

        mov [wcex.hIcon],eax

        mov [wcex.hIconSm],eax

        ; load the cursor

        invoke LoadCursor,NULL,IDC_ARROW

        mov [wcex.hCursor],eax

        ; the brush for the background

        mov [wcex.hbrBackground],COLOR_WINDOW+1

        ; the windows class name

        mov dword [wcex.lpszClassName],szClass

        ; set to NULL

        mov [wcex.cbClsExtra],0

        mov [wcex.cbWndExtra],0

        mov dword [wcex.lpszMenuName],NULL

        ; register wcex

        ; RegisterClassEx(&wcex)

        invoke RegisterClassEx,wcex

        test eax,eax

        jz reg_error

        ; create the window

        invoke CreateWindowEx,0,szClass,szTitle,WS_OVERLAPPEDWINDOW,\
                              CW_USEDEFAULT,CW_USEDEFAULT,\
                              500,100,NULL,NULL,[wcex.hInstance],NULL

        test eax,eax

        jz cr_error

        mov [h_wnd],eax

        ; show and update the window

        ; ShowWindow(hWnd,SW_SHOWNORMAL)

        invoke ShowWindow,[h_wnd],SW_SHOWNORMAL

        ; UpdateWindow(hWnd)

        invoke UpdateWindow,[h_wnd]

  msg_loop:

        ; the main message loop

        ; GetMessage(&msg,NULL,0,0)

        invoke GetMessage,msg,NULL,0,0

        cmp eax,1

        jb exit

        jne msg_loop

        ; TranslateMessage(&msg)

        invoke TranslateMessage,msg

        ; DispatchMessage(&msg)

        invoke DispatchMessage,msg

        jmp msg_loop

  reg_error:

        invoke MessageBox,NULL,szRegError,szTitle,MB_ICONERROR+MB_OK

        jmp exit

  cr_error:

        invoke MessageBox,NULL,szCreateError,szTitle,MB_ICONERROR+MB_OK

  exit:

        ; return msg.wParam

        invoke  ExitProcess,[msg.wParam]

; -------------------------------------------------------------------------------------

proc WndProc uses ebx esi edi,hwnd,wmsg,wparam,lparam

  ; WndProc(hwnd,wmsg,wparam,lparam)

  ; callback function to process messages for the main window

        cmp [wmsg],WM_PAINT

        je .PAINT

        cmp [wmsg],WM_DESTROY

        je .DESTROY

  .DEFAULT:

        ; DefWindowProc(hWnd,message,wParam,lParam)

        invoke DefWindowProc,[hwnd],[wmsg],[wparam],[lparam]

        jmp .DONE

  .PAINT:

        ; hdc = BeginPaint(hWnd,&ps)

        invoke BeginPaint,[hwnd],ps

        mov [hdc],eax

        ; TextOut(hdc,5,5,greeting,len(greeting))

        invoke TextOut,[hdc],5,5,szGreeting,12

        ; EndPaint(hWnd,&ps)

        invoke EndPaint,[hwnd],ps

        jmp .DONE

  .DESTROY:

        ; PostQuitMessage(0)

        invoke PostQuitMessage,0

        xor eax,eax

  .DONE:

        ret

endp

; -------------------------------------------------------------------------------------

section '.idata' import data readable writeable

  library kernel,'KERNEL32.DLL',\
          user,'USER32.DLL',\
          gdi,'GDI32.DLL'

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

  import user,\
         RegisterClassEx,'RegisterClassExA',\
         CreateWindowEx,'CreateWindowExA',\
         ShowWindow,'ShowWindow',\
         UpdateWindow,'UpdateWindow',\
         GetMessage,'GetMessageA',\
         TranslateMessage,'TranslateMessage',\
         DispatchMessage,'DispatchMessageA',\
         MessageBox,'MessageBoxA',\
         DefWindowProc,'DefWindowProcA',\
         BeginPaint,'BeginPaint',\
         EndPaint,'EndPaint',\
         PostQuitMessage,'PostQuitMessage',\
         LoadIcon,'LoadIconA',\
         LoadCursor,'LoadCursorA'

  import gdi,\
         TextOut,'TextOutA'

; -------------------------------------------------------------------------------------

section '.data' readable writeable

  szClass TCHAR "Win32app",0

  szTitle TCHAR "Win32 Application",0 

  szGreeting TCHAR "Hello World!",0

  szRegError TCHAR "Call to RegisterClassEx failed!",0

  szCreateError TCHAR "Call to CreateWindowEx failed!",0

  wcex WNDCLASSEX

  ps PAINTSTRUCT

  msg MSG

  h_wnd dd 0

  hdc dd 0

; -------------------------------------------------------------------------------------
Advertisements

Blog at WordPress.com.

%d bloggers like this: