Assembly language examples using NASM on Windows
Basic Window - 32 bit
Description
Creates a basic window, 32 bit. This could be used as the starting point for a larger GUI application.
Assemble
- nasm -f win32 BasicWindow32.asm -o BasicWindow32.obj
Link
- golink /entry:Start kernel32.dll user32.dll BasicWindow32.obj
- polink /ENTRY:Start /SUBSYSTEM:WINDOWS /LIBPATH:c:\lib32 kernel32.lib user32.lib BasicWindow32.obj
Notes
Double click the icon to run the executable.
The window can only be moved, resized and closed.
The window is not centred on the screen.
The window is the correct width and height, but we actually wanted the client area that size instead. This is due to the window frame
and menu bar not being taken in to consideration.
Code
COLOR_WINDOW EQU 5
CS_BYTEALIGNWINDOW EQU 2000h
CS_HREDRAW EQU 2
CS_VREDRAW EQU 1
CW_USEDEFAULT EQU 80000000h
IDC_ARROW EQU 7F00h
IDI_APPLICATION EQU 7F00h
IMAGE_CURSOR EQU 2
IMAGE_ICON EQU 1
LR_SHARED EQU 8000h
NULL EQU 0
SW_SHOWNORMAL EQU 1
WM_DESTROY EQU 2
WS_EX_COMPOSITED EQU 2000000h
WS_OVERLAPPEDWINDOW EQU 0CF0000h
WindowWidth EQU 640
WindowHeight EQU 480
extern _CreateWindowExA@48
extern _DefWindowProcA@16
extern _DispatchMessageA@4
extern _ExitProcess@4
extern _GetMessageA@16
extern _GetModuleHandleA@4
extern _IsDialogMessageA@8
extern _LoadImageA@24
extern _PostQuitMessage@4
extern _RegisterClassExA@4
extern _ShowWindow@8
extern _TranslateMessage@4
extern _UpdateWindow@4
global Start
section .data
WindowName db "Basic Window 32", 0
ClassName db "Window", 0
section .bss
hInstance resd 1
section .text
Start:
push NULL
call _GetModuleHandleA@4
mov dword [hInstance], EAX
call WinMain
.Exit:
push NULL
call _ExitProcess@4
WinMain:
push EBP
mov EBP, ESP
sub ESP, 80
%define wc EBP - 80
%define wc.cbSize EBP - 80
%define wc.style EBP - 76
%define wc.lpfnWndProc EBP - 72
%define wc.cbClsExtra EBP - 68
%define wc.cbWndExtra EBP - 64
%define wc.hInstance EBP - 60
%define wc.hIcon EBP - 56
%define wc.hCursor EBP - 52
%define wc.hbrBackground EBP - 48
%define wc.lpszMenuName EBP - 44
%define wc.lpszClassName EBP - 40
%define wc.hIconSm EBP - 36
%define msg EBP - 32
%define msg.hwnd EBP - 32
%define msg.message EBP - 28
%define msg.wParam EBP - 24
%define msg.lParam EBP - 20
%define msg.time EBP - 16
%define msg.pt.x EBP - 12
%define msg.pt.y EBP - 8
%define hWnd EBP - 4
mov dword [wc.cbSize], 48
mov dword [wc.style], CS_HREDRAW | CS_VREDRAW | CS_BYTEALIGNWINDOW
mov dword [wc.lpfnWndProc], WndProc
mov dword [wc.cbClsExtra], NULL
mov dword [wc.cbWndExtra], NULL
mov EAX, dword [hInstance]
mov dword [wc.hInstance], EAX
push LR_SHARED
push NULL
push NULL
push IMAGE_ICON
push IDI_APPLICATION
push NULL
call _LoadImageA@24
mov dword [wc.hIcon], EAX
push LR_SHARED
push NULL
push NULL
push IMAGE_CURSOR
push IDC_ARROW
push NULL
call _LoadImageA@24
mov dword [wc.hCursor], EAX
mov dword [wc.hbrBackground], COLOR_WINDOW + 1
mov dword [wc.lpszMenuName], NULL
mov dword [wc.lpszClassName], ClassName
push LR_SHARED
push NULL
push NULL
push IMAGE_ICON
push IDI_APPLICATION
push NULL
call _LoadImageA@24
mov dword [wc.hIconSm], EAX
lea EAX, [wc]
push EAX
call _RegisterClassExA@4
push NULL
push dword [hInstance]
push NULL
push NULL
push WindowHeight
push WindowWidth
push CW_USEDEFAULT
push CW_USEDEFAULT
push WS_OVERLAPPEDWINDOW
push WindowName
push ClassName
push WS_EX_COMPOSITED
call _CreateWindowExA@48
mov dword [hWnd], EAX
push SW_SHOWNORMAL
push dword [hWnd]
call _ShowWindow@8
push dword [hWnd]
call _UpdateWindow@4
.MessageLoop:
lea EAX, [msg]
push NULL
push NULL
push NULL
push EAX
call _GetMessageA@16
cmp EAX, 0
je .Done
lea EAX, [msg]
push EAX
push dword [hWnd]
call _IsDialogMessageA@8
cmp EAX, 0
jne .MessageLoop
lea EAX, [msg]
push EAX
call _TranslateMessage@4
lea EAX, [msg]
push EAX
call _DispatchMessageA@4
jmp .MessageLoop
.Done:
mov ESP, EBP
pop EBP
xor EAX, EAX
ret
WndProc:
push EBP
mov EBP, ESP
%define hWnd EBP + 8
%define uMsg EBP + 12
%define wParam EBP + 16
%define lParam EBP + 20
cmp dword [uMsg], WM_DESTROY
je WMDESTROY
DefaultMessage:
push dword [lParam]
push dword [wParam]
push dword [uMsg]
push dword [hWnd]
call _DefWindowProcA@16
mov ESP, EBP
pop EBP
ret 16
WMDESTROY:
push NULL
call _PostQuitMessage@4
xor EAX, EAX
mov ESP, EBP
pop EBP
ret 16