View difference between Paste ID: r7MSEwcg and Pmvr4r1S
SHOW: | | - or go back to the newest paste.
1
;-------------------------------------------------------------------------------------------------------------------
2
; Hello, Windows!  in x86 ASM - (c) 2021 Dave's Garage - Use at your own risk, no warranty!
3
;-------------------------------------------------------------------------------------------------------------------
4
5
; Compiler directives and includes
6
7
.386						; Full 80386 instruction set and mode
8
.model flat, stdcall				; All 32-bit and later apps are flat. Used to include "tiny, etc"
9
option casemap:none				; Preserve the case of system identifiers but not our own, more or less
10
11
12
; Include files - headers and libs that we need for calling the system dlls like user32, gdi32, kernel32, etc
13
include \masm32\include\windows.inc		; Main windows header file (akin to Windows.h in C)
14
include \masm32\include\user32.inc		; Windows, controls, etc
15
include \masm32\include\kernel32.inc		; Handles, modules, paths, etc
16
include \masm32\include\gdi32.inc		; Drawing into a device context (ie: painting)
17
18
; Libs - information needed to link ou binary to the system DLL callss
19
20
includelib \masm32\lib\kernel32.lib		; Kernel32.dll
21
includelib \masm32\lib\user32.lib		; User32.dll
22
includelib \masm32\lib\gdi32.lib		; GDI32.dll
23
24
; Forward declarations - Our main entry point will call forward to WinMain, so we need to define it here
25
26
WinMain proto :DWORD, :DWORD, :DWORD, :DWORD	; Forward decl for MainEntry 
27
28
; Constants and Datra
29
30
WindowWidth	equ 640				; How big we'd like our main window
31
WindowHeight	equ 480
32
33
.DATA
34
35
ClassName    	db "MyWinClass", 0		; The name of our Window class
36
AppName		db "Dave's Tiny App", 0		; The name of our main window
37
38
.DATA?						; Uninitialized data - Basically just reserves address space
39
40
hInstance	HINSTANCE ?			; Instance handle (like the process id) of our application
41
CommandLine	LPSTR	  ?                     ; Pointer to the command line text we were launched with
42
43
;-------------------------------------------------------------------------------------------------------------------
44
.CODE						; Here is where the program itself lives
45
;-------------------------------------------------------------------------------------------------------------------
46
47
MainEntry proc
48
49
	LOCAL	sui:STARTUPINFOA		; Reserve stack space so we can load and inspect the STARTUPINFO
50
51
	push	NULL				; Get the instance handle of our app (NULL means ourselves)
52
	call 	GetModuleHandle			; GetModuleHandle will return instance handle in EAX
53
	mov	hInstance, eax			; Cache it in our global variable
54
55
	call	GetCommandLineA			; Get the command line text ptr in EAX to pass on to main
56
	mov	CommandLine, eax
57
58
	; Call our WinMain and then exit the process with whatever comes back from it
59
60
	; Please check this, I have only typed it, not tested it :-)
61
62
	lea	eax, sui			; Get the STARTUPINFO for this process
63
	push	eax
64
	call	GetStartupInfoA			; Find out if wShowWindow should be used
65
	test	sui.dwFlags, STARTF_USESHOWWINDOW   
66
	jz	@1
67
	push	sui.wShowWindow			; If the show window flag bit was nonzero, we use wShowWindow
68
	jmp	@2
69
@1:
70
	push	SW_SHOWDEFAULT			; Use the default 
71
@2:	
72
	push	CommandLine
73
	push	NULL
74
	push	hInstance
75
	call	WinMain
76
77
	push	eax
78
	call	ExitProcess
79
80
MainEntry endp
81
82
; 
83
; WinMain - The traditional signature for the main entry point of a Windows programa
84
;
85
86
WinMain proc hInst:HINSTANCE, hPrevInst:HINSTANCE, CmdLine:LPSTR, CmdShow:DWORD
87
88
	LOCAL	wc:WNDCLASSEX			; Create these vars on the stack, hence LOCAL
89
	LOCAL	msg:MSG
90
	LOCAL	hwnd:HWND
91
92
	mov	wc.cbSize, SIZEOF WNDCLASSEX		; Fill in the values in the members of our windowclass
93
	mov	wc.style, CS_HREDRAW or CS_VREDRAW	; Redraw if resized in either dimension
94
	mov	wc.lpfnWndProc, OFFSET WndProc		; Our callback function to handle window messages
95
	mov	wc.cbClsExtra, 0			; No extra class data
96
	mov	wc.cbWndExtra, 0			; No exttra window data
97
	mov	eax, hInstance
98
	mov	wc.hInstance, eax			; Our instance handle
99
	mov	wc.hbrBackground, COLOR_3DSHADOW+1	; Default brush colors are color plus one
100
	mov	wc.lpszMenuName, NULL			; No app menu
101
	mov	wc.lpszClassName, OFFSET ClassName	; The window's class name
102
103
	push	IDI_APPLICATION				; Use the default application icon
104
	push	NULL	
105
	call 	LoadIcon
106
	mov	wc.hIcon, eax
107
	mov	wc.hIconSm, eax
108
109
	push	IDC_ARROW				; Get the default "arrow" mouse cursor
110
	push	NULL
111
	call	LoadCursor
112
	mov	wc.hCursor, eax
113
114
	lea	eax, wc
115
	push	eax
116
	call	RegisterClassEx				; Register the window class 
117
118
	push	NULL					; Bonus data, but we have none, so null
119
	push	hInstance				; Our app instance handle
120
	push	NULL					; Menu handle
121
	push	NULL					; Parent window (if we were a child window)
122
	push	WindowHeight				; Our requested height
123
	push	WindowWidth				; Our requested width
124
	push	CW_USEDEFAULT				; Y
125
	push	CW_USEDEFAULT				; X
126
	push	WS_OVERLAPPEDWINDOW + WS_VISIBLE	; Window stytle (normal and visible)
127
	push	OFFSET AppName				; The window title (our application name)
128
	push	OFFSET ClassName			; The window class name of what we're creating
129
	push	0					; Extended style bits, if any
130
	call 	CreateWindowExA
131
	cmp	eax, NULL
132
	je	WinMainRet				; Fail and bail on NULL handle returned
133
	mov	hwnd, eax				; Window handle is the result, returned in eax
134
135
	push	eax					; Force a paint of our window
136
	call	UpdateWindow
137
138
MessageLoop:
139
140
	push	0
141
	push 	0
142
	push	NULL
143
	lea	eax, msg
144
	push	eax
145
	call	GetMessage				; Get a message from the application's message queue
146
147
	cmp	eax, 0					; When GetMessage returns 0, it's time to exit
148
	je	DoneMessages
149
150
	lea	eax, msg				; Translate 'msg'
151
	push	eax
152
	call	TranslateMessage
153
154
	lea	eax, msg				; Dispatch 'msg'
155
	push	eax
156
	call	DispatchMessage
157
158
	jmp	MessageLoop
159
160
DoneMessages:
161
	
162
	mov	eax, msg.wParam				; Return wParam of last message processed
163
164
WinMainRet:
165
	
166
	ret
167
168
WinMain endp
169
170
;
171
; WndProc - Our Main Window Procedure, handles painting and exiting
172
;
173
174
WndProc proc hWnd:HWND, uMsg:UINT, wParam:WPARAM, lParam:LPARAM
175
176
	LOCAL 	ps:PAINTSTRUCT				; Local stack variables
177
	LOCAL	rect:RECT
178
	LOCAL	hdc:HDC
179
180
	cmp	uMsg, WM_DESTROY
181
	jne	NotWMDestroy
182
183
	push	0					; WM_DESTROY received, post our quit msg
184
	call	PostQuitMessage				; Quit our application
185
	xor	eax, eax				; Return 0 to indicate we handled it
186
	ret
187
188
NotWMDestroy:
189
190
	cmp	uMsg, WM_PAINT
191
	jne	NotWMPaint
192
193
	lea	eax, ps					; WM_PAINT received
194
	push	eax
195
	push	hWnd
196
	call	BeginPaint				; Go get a device context to paint into
197
	mov	hdc, eax
198
199
	push	TRANSPARENT
200
	push	hdc
201
	call	SetBkMode				; Make text have a transparent background
202
203
	lea	eax, rect				; Figure out how big the client area is so that we
204
	push	eax					;   can center our content over it
205
	push	hWnd
206
	call	GetClientRect
207
208
	push	DT_SINGLELINE + DT_CENTER + DT_VCENTER
209
	lea	eax, rect
210
	push	eax
211
	push	-1
212
	push	OFFSET AppName
213
	push	hdc
214
	call	DrawText				; Draw text centered vertically and horizontally
215
216
	lea	eax, ps
217
	push	eax
218
	push	hWnd
219
	call	EndPaint				; Wrap up painting
220
221
	xor	eax, eax				; Return 0 as no further processing needed
222
	ret
223
224
NotWMPaint:
225
	
226
	push	lParam
227
	push	wParam
228
	push	uMsg
229
	push	hWnd
230
	call	DefWindowProc				; Forward message on to default processing and
231
	ret						;   return whatever it does
232
233
WndProc endp
234
235
END MainEntry						; Specify entry point, else _WinMainCRTStartup is assumed
236
 
237