For a year now, it keeps hacking me on Windows. And when I am in a bad mood, I turn to complex things. Today, I wanted to see if I could make a functional assembly code with Microsoft's Copilot artificial intelligence and my assembly knowledge with FASM. Here is what resulted.
The program is a Win32 GUI application written in FASM that draws a crosshair (vertical + horizontal line) following the mouse cursor inside a window classic GDI.
1. Window Setup
The app starts by registering a Win32 window class (WNDCLASSEX) and creating a standard
overlapped window. Nothing unusual here — just the classic Win32 boilerplate.
2. Message Loop
The program enters the main loop:
- GetMessage
- TranslateMessage
- DispatchMessage
This keeps the window responsive and forwards events to the window procedure.
3. Tracking the Mouse
Whenever the mouse moves inside the window, Windows sends a WM_MOUSEMOVE message.
The program extracts the X and Y coordinates from lParam:
- LOWORD(lParam) → X
- HIWORD(lParam) → Y
These values are stored and the window is invalidated so it can be repainted.
4. Drawing the Crosshair (GDI)
All drawing happens inside WM_PAINT using classic GDI:
- MoveToEx
- LineTo
- Ellipse
- TextOut
- FillRect
The steps are:
- Clear the client area
- Get the window’s current size (GetClientRect)
- Draw a vertical line at the mouse’s X position
- Draw a horizontal line at the mouse’s Y position
- Draw a small circle at the intersection
- Print the coordinates in the corner
Because the client size is read dynamically, the crosshair always stretches across the entire window —
no matter how it’s resized.

See the source code
; mouse_crosshair.asm
format PE GUI 4.0
entry start
include "win32a.inc"
WM_MOUSEMOVE = 0x0200
section '.data' data readable writeable
szClass db "MouseGraph",0
szTitle db "Mouse Crosshair Demo",0
mouseX dd 0
mouseY dd 0
fmt db "X=%d Y=%d",0
buffer db 64 dup(0)
rc RECT
ps PAINTSTRUCT
wc WNDCLASSEX
msg MSG
section '.code' code readable executable
start:
invoke GetModuleHandle,0
mov [wc.hInstance],eax
mov [wc.cbSize],sizeof.WNDCLASSEX
mov [wc.style],CS_HREDRAW or CS_VREDRAW
mov [wc.lpfnWndProc],WndProc
mov [wc.cbClsExtra],0
mov [wc.cbWndExtra],0
mov [wc.hIcon],0
mov [wc.hIconSm],0
mov [wc.lpszMenuName],0
mov [wc.lpszClassName],szClass
mov [wc.hbrBackground],COLOR_WINDOW+1
invoke LoadCursor,0,IDC_ARROW
mov [wc.hCursor],eax
invoke RegisterClassEx,wc
invoke CreateWindowEx,0,szClass,szTitle,\
WS_VISIBLE+WS_OVERLAPPEDWINDOW,\
200,200,800,600,0,0,[wc.hInstance],0
msg_loop:
invoke GetMessage,msg,0,0,0
test eax,eax
jz exit
invoke TranslateMessage,msg
invoke DispatchMessage,msg
jmp msg_loop
exit:
invoke ExitProcess,0
; ---------------------------------------------------------
proc WndProc hWnd,uMsg,wParam,lParam
cmp [uMsg],WM_MOUSEMOVE
je .mouse
cmp [uMsg],WM_PAINT
je .paint
cmp [uMsg],WM_DESTROY
je .destroy
.def:
invoke DefWindowProc,[hWnd],[uMsg],[wParam],[lParam]
ret
; ---------------- WM_MOUSEMOVE ----------------
.mouse:
mov eax,[lParam]
and eax,0FFFFh
mov [mouseX],eax
mov eax,[lParam]
shr eax,16
and eax,0FFFFh
mov [mouseY],eax
invoke InvalidateRect,[hWnd],0,TRUE
ret
; ---------------- WM_PAINT ----------------
.paint:
invoke BeginPaint,[hWnd],ps
mov esi,eax ; hdc
; clean client
invoke GetClientRect,[hWnd],rc
invoke FillRect,esi,rc,COLOR_WINDOW+1
; pen red
invoke CreatePen,PS_SOLID,1,0x0000FF
mov ebx,eax
invoke SelectObject,esi,ebx
; ---------------- linie verticala (cruce) ----------------
mov eax,[mouseX] ; X constant
mov edx,[rc.bottom] ; Y max (jos)
invoke MoveToEx,esi,eax,0,0
invoke LineTo,esi,eax,edx
; ---------------- line ----------------
mov eax,[mouseY] ; Y constant
mov edx,[rc.right] ; X max (dreapta)
invoke MoveToEx,esi,0,eax,0
invoke LineTo,esi,edx,eax
; punct în intersec?ie
mov eax,[mouseX]
mov edx,[mouseY]
invoke Ellipse,esi,eax-4,edx-4,eax+4,edx+4
; text coordonate
invoke wsprintf,buffer,fmt,[mouseX],[mouseY]
invoke lstrlen,buffer
invoke TextOut,esi,10,10,buffer,eax
invoke EndPaint,[hWnd],ps
ret
; ---------------- WM_DESTROY ----------------
.destroy:
invoke PostQuitMessage,0
ret
endp
section '.idata' import data readable
library kernel32,"KERNEL32.DLL",\
user32,"USER32.DLL",\
gdi32,"GDI32.DLL"
include "api/kernel32.inc"
include "api/user32.inc"
include "api/gdi32.inc"

