1. Получить дискриптор Вашей программы(обязательно)
2. Получить указатель на командную строку(не обязательно)
3. Зарегистрировать класс окна(не требуется, если Вы используете встроенный тип окна, например MessageBox)
4. Создать окно(обязательно)
5. Показать окно(если хотите немедленно показать окно)
6. Обновить окно
7. Образовать бесконечный цикл, обрабатывающий сообщения окна
8. Если есть сообщения, то обработать специализированной функцией ответственной за окно
9. Выйти из программы, если пользователь закрыл окно

Разберем простую программу, которая выводит только окно.

Я взял пример программы Wap32.asm из пакета TASM и несколько упостил ее.

.386
.model flat, stdcall
include win32.inc
Файл win32.inc содержит  некоторые нужные константы и структуры

extrn  CreateWindowExA:PROC
extrn DefWindowProcA:PROC
extrn  DispatchMessageA:PROC
extrn ExitProcess:PROC
extrn  GetMessageA:PROC
extrn GetModuleHandleA:PROC
extrn  LoadCursorA:PROC
extrn LoadIconA:PROC
extrn PostQuitMessage:PROC
extrn  RegisterClassA:PROC
extrn ShowWindow:PROC
extrn  TranslateMessage:PROC
extrn UpdateWindow:PROC

.data

newhwnd  dd 0
msg MSGSTRUCT <?>
wc WNDCLASS <?>
hInst dd  0
szTitleName db 'Win32 Assembly Program',0
szClassName db  'ASMCLASS32',0

.code
start:

push 0
call  GetModuleHandleA
mov [hInst], eax

Получим дискриптор  программы.

Далее инициализируем структуру WndClass для регистрации  окна

mov [wc.clsStyle], CS_HREDRAW + CS_VREDRAW +  CS_GLOBALCLASS

clsStyle - определяет стиль класса

mov  [wc.clsLpfnWndProc], offset WndProc

clsLpfnWndProc - указывает на  процедуру окна

mov [wc.clsCbClsExtra], 0
mov [wc.clsCbWndExtra],  0

mov eax, [hInst]
mov [wc.clsHInstance], eax

clsHInstance -  содержит дискриптор программы

push IDI_APPLICATION
push 0
call  LoadIconA
mov [wc.clsHIcon], eax

push IDC_ARROW
push 0
call  LoadCursorA
mov [wc.clsHCursor], eax

mov [wc.clsHbrBackground],  COLOR_WINDOW + 1
mov dword ptr [wc.clsLpszMenuName], 0
mov dword ptr  [wc.clsLpszClassName], offset szClassName

clsLpszClassName - определяет  имя класса окна

push offset wc
call RegisterClassA

Создаем  окно:

push 0
push [hInst] ; дискриптор окна
push 0
push  0
push CW_USEDEFAULT ; высота
push CW_USEDEFAULT ; ширина
push  CW_USEDEFAULT ; y
push CW_USEDEFAULT ; x
push WS_OVERLAPPEDWINDOW ;  стиль
push offset szTitleName ; заголовок окна
push offset szClassName ;  имя класса
push 0 ; дополнительный стиль

call  CreateWindowExA

mov [newhwnd], eax

newhwnd - дискриптор  окна

Покажем окно:

push SW_SHOWNORMAL
push [newhwnd]
call  ShowWindow

Обновим окно:

push [newhwnd]
call  UpdateWindow

Создаем цикл для обработки сообщений  окна

msg_loop:
push 0
push 0
push 0
push offset msg
call  GetMessageA

cmp ax, 0
je end_loop

push offset msg
call  TranslateMessage

push offset msg
call DispatchMessageA

jmp  msg_loop

end_loop:

выход из программы: push [msg.msWPARAM] call  ExitProcess

Процедура окна:

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

Win32 требует, чтобы  EBX, EDI, и ESI были сохранены

cmp [wmsg], WM_DESTROY
je  wmdestroy

push [lparam]
push [wparam]
push [wmsg]
push  [hwnd]
call DefWindowProcA
jmp finish

wmdestroy:
push 0
call  PostQuitMessage
mov eax, 0
finish:
ret
WndProc endp
ends
end  start

На первый взгляд кажется, что слишком много написано для простой программы. На самом же деле писать все полностью не нужно, достаточно написать файл один раз, а потом использовать его как шаблон для своих новых программ. Можно создать объектный файл и использовать его как загрузочный код, а писать только процедуру окна(WinProc).