1
2;--- A simple Windows GUI program that creates an empty window;
3;--- similar to Win64_2, but with SEH support and without using hll
4;--- directives. Thus this source can be assembled by both JWasm
5;--- and Masm64 - Masm64 v8 might have problems, though.
6;---
7;--- to assemble enter:
8;---   JWasm -win64 Win64_3.asm
9;--- or:
10;---   ml64 -c Win64_3.asm
11;---
12;--- to link the binary use:
13;---   MS Link: link Win64_3.obj
14;---   JWlink:  jwlink format win pe ru win file Win64_3.obj op start=WinMainCRTStartup
15
16    option casemap:none
17
18    includelib kernel32.lib
19    includelib user32.lib
20
21HINSTANCE typedef ptr
22HWND      typedef ptr
23HMENU     typedef ptr
24HICON     typedef ptr
25HBRUSH    typedef ptr
26HCURSOR   typedef ptr
27WPARAM    typedef QWORD
28LPARAM    typedef QWORD
29LPSTR     typedef ptr BYTE
30LPVOID    typedef ptr
31UINT      typedef DWORD
32
33NULL           equ 0
34WS_OVERLAPPEDWINDOW equ 0CF0000h
35CW_USEDEFAULT  equ 80000000h
36SW_SHOWDEFAULT equ 10
37SW_SHOWNORMAL  equ 1
38IDC_ARROW      equ 32512
39IDI_APPLICATION equ 32512
40WM_DESTROY     equ 2
41CS_VREDRAW     equ 1
42CS_HREDRAW     equ 2
43COLOR_WINDOW   equ 5
44
45proto_WNDPROC typedef proto :HWND,:UINT,:WPARAM,:LPARAM
46WNDPROC typedef ptr proto_WNDPROC
47
48WNDCLASSEXA struct 8
49cbSize          DWORD   ?
50style           DWORD   ?
51lpfnWndProc     WNDPROC ?
52cbClsExtra      DWORD   ?
53cbWndExtra      DWORD   ?
54hInstance       HINSTANCE ?
55hIcon           HICON   ?
56hCursor         HCURSOR ?
57hbrBackground   HBRUSH  ?
58lpszMenuName    LPSTR   ?
59lpszClassName   LPSTR   ?
60hIconSm         HICON   ?
61WNDCLASSEXA ends
62
63POINT   struct
64x   SDWORD  ?
65y   SDWORD  ?
66POINT   ends
67
68MSG struct 8
69hwnd    HWND    ?
70message DWORD   ?
71wParam  WPARAM  ?
72lParam  LPARAM  ?
73time    DWORD   ?
74pt      POINT   <>
75MSG ends
76
77GetModuleHandleA proto :LPSTR
78GetCommandLineA  proto
79ExitProcess      proto :UINT
80LoadIconA        proto :HINSTANCE, :LPSTR
81LoadCursorA      proto :HINSTANCE, :LPSTR
82RegisterClassExA proto :ptr WNDCLASSEXA
83CreateWindowExA  proto :DWORD, :LPSTR, :LPSTR, :DWORD, :SDWORD, :SDWORD, :SDWORD, :SDWORD, :HWND, :HMENU, :HINSTANCE, :LPVOID
84ShowWindow       proto :HWND, :SDWORD
85UpdateWindow     proto :HWND
86GetMessageA      proto :ptr MSG, :HWND, :SDWORD, :SDWORD
87TranslateMessage proto :ptr MSG
88DispatchMessageA proto :ptr MSG
89PostQuitMessage  proto :SDWORD
90DefWindowProcA   proto :HWND, :UINT, :WPARAM, :LPARAM
91
92;WinMain proto :HINSTANCE, :HINSTANCE, :LPSTR, :UINT
93
94    .data
95
96ClassName db "SimpleWinClass",0
97AppName  db "Our First Window",0
98
99    .data?
100
101hInstance HINSTANCE ?
102CommandLine LPSTR ?
103
104    .code
105
106WinMainCRTStartup proc FRAME
107
108    sub    rsp,5*8
109    .allocstack 5*8
110    .endprolog
111
112    mov    ecx,NULL
113    call   GetModuleHandleA
114    mov    hInstance, rax
115    call   GetCommandLineA
116    mov    CommandLine, rax
117    mov    rcx, hInstance
118    mov    rdx, NULL
119    mov    r8, CommandLine
120    mov    r9d, SW_SHOWDEFAULT
121    call   WinMain
122    mov    ecx, eax
123    call   ExitProcess
124    align 4
125WinMainCRTStartup endp
126
127WinMain proc FRAME hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:UINT
128
129local wc:WNDCLASSEXA
130local msg:MSG
131local hwnd:HWND
132
133    push  rbp
134    .pushreg rbp
135    mov   rbp,rsp
136    .setframe rbp, 0
137    sub   rsp, sizeof WNDCLASSEXA + sizeof MSG + sizeof HWND + 13*8  ;make sure rsp is 16-byte aligned
138    .allocstack sizeof WNDCLASSEXA + sizeof MSG + sizeof HWND + 13*8
139    .endprolog
140
141;--- store params in shadow space
142    mov   hInst, rcx
143    mov   hPrevInst, rdx
144    mov   CmdLine, r8
145    mov   CmdShow, r9d
146
147    mov   wc.cbSize, SIZEOF WNDCLASSEXA
148    mov   wc.style, CS_HREDRAW or CS_VREDRAW
149;   mov   rax, OFFSET WndProc  ;using LEA is preferable
150    lea   rax, [WndProc]
151    mov   wc.lpfnWndProc, rax
152    mov   wc.cbClsExtra, 0
153    mov   wc.cbWndExtra, 0
154    mov   wc.hInstance, rcx
155    mov   wc.hbrBackground, COLOR_WINDOW+1
156    mov   wc.lpszMenuName, NULL
157;    mov   rax, OFFSET ClassName  ;using LEA is preferable
158    lea   rax, [ClassName]
159    mov   wc.lpszClassName, rax
160    mov   ecx, NULL
161    mov   edx, IDI_APPLICATION
162    call  LoadIconA
163    mov   wc.hIcon, rax
164    mov   wc.hIconSm, rax
165    mov   ecx, NULL
166    mov   edx, IDC_ARROW
167    call  LoadCursorA
168    mov   wc.hCursor,rax
169    lea   rcx, wc
170    call  RegisterClassExA
171    mov   ecx, NULL
172    lea   rdx, [ClassName]
173    lea   r8, [AppName]
174    mov   r9d, WS_OVERLAPPEDWINDOW
175    mov   dword ptr [rsp+4*8], CW_USEDEFAULT
176    mov   dword ptr [rsp+5*8], CW_USEDEFAULT
177    mov   dword ptr [rsp+6*8], CW_USEDEFAULT
178    mov   dword ptr [rsp+7*8], CW_USEDEFAULT
179    mov   qword ptr [rsp+8*8], NULL
180    mov   qword ptr [rsp+9*8], NULL
181    mov   rax, hInst
182    mov   [rsp+10*8], rax
183    mov   qword ptr [rsp+11*8], NULL
184    call  CreateWindowExA
185    mov   hwnd,rax
186    mov   rcx, hwnd
187    mov   edx, SW_SHOWNORMAL
188    call  ShowWindow
189    mov   rcx, hwnd
190    call  UpdateWindow
191;--- message loop
192@@:
193        lea rcx, msg
194        mov rdx, NULL
195        mov r8, 0
196        mov r9, 0
197        call GetMessageA
198        and rax, rax
199        jz @F
200        lea rcx, msg
201        call TranslateMessage
202        lea rcx, msg
203        call DispatchMessageA
204        jmp @B
205@@:
206    mov   rax, msg.wParam
207    add   rsp, sizeof WNDCLASSEXA + sizeof MSG + sizeof HWND + 13*8
208    pop   rbp
209;--- RET 0 is used, because ML64 seems to have problems with a simple RET
210    ret 0
211    align 4
212WinMain endp
213
214WndProc proc FRAME hwnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
215
216    sub   rsp, 5*8
217    .allocstack 5*8
218    .endprolog
219
220    cmp edx, WM_DESTROY
221    jnz @F
222    mov ecx, NULL
223    call PostQuitMessage
224    xor rax,rax
225    jmp exit
226@@:
227    call DefWindowProcA
228exit:
229    add rsp, 5*8
230    ret 0
231    align 4
232WndProc endp
233
234end
235