Win64_3 - SEH Support in Win64
;--- This sample shows how to use SEH primitives. It doesn't use hll
;--- directives. Thus this source can be assembled by both JWasm
;--- and Masm64.
;---
;--- to assemble enter:
;--- JWasm -win64 Win64_3.asm
;--- or:
;--- ml64 -c Win64_3.asm
;---
;--- to link the binary enter:
;--- Link Win64_3.obj
option casemap:none
includelib kernel32.lib
includelib user32.lib
HINSTANCE typedef QWORD
HWND typedef QWORD
HMENU typedef QWORD
HICON typedef QWORD
HBRUSH typedef QWORD
HCURSOR typedef QWORD
WPARAM typedef QWORD
LPARAM typedef QWORD
LPSTR typedef QWORD
LPVOID typedef QWORD
UINT typedef DWORD
NULL equ 0
WS_OVERLAPPEDWINDOW equ 0CF0000h
CW_USEDEFAULT equ 80000000h
SW_SHOWDEFAULT equ 10
SW_SHOWNORMAL equ 1
IDC_ARROW equ 32512
IDI_APPLICATION equ 32512
WM_DESTROY equ 2
CS_VREDRAW equ 1
CS_HREDRAW equ 2
COLOR_WINDOW equ 5
proto_WNDPROC typedef proto :HWND,:QWORD,:WPARAM,:LPARAM
WNDPROC typedef ptr proto_WNDPROC
WNDCLASSEXA struct 8
cbSize DWORD ?
style DWORD ?
lpfnWndProc WNDPROC ?
cbClsExtra DWORD ?
cbWndExtra DWORD ?
hInstance HINSTANCE ?
hIcon HICON ?
hCursor HCURSOR ?
hbrBackground HBRUSH ?
lpszMenuName LPSTR ?
lpszClassName LPSTR ?
hIconSm HICON ?
WNDCLASSEXA ends
POINT struct
x SDWORD ?
y SDWORD ?
POINT ends
MSG struct 8
hwnd HWND ?
message DWORD ?
wParam WPARAM ?
lParam LPARAM ?
time DWORD ?
pt POINT <>
MSG ends
GetModuleHandleA proto :LPSTR
GetCommandLineA proto
ExitProcess proto :UINT
LoadIconA proto :HINSTANCE, :LPSTR
LoadCursorA proto :HINSTANCE, :LPSTR
RegisterClassExA proto :ptr WNDCLASSEXA
CreateWindowExA proto :DWORD, :LPSTR, :LPSTR, :DWORD, :SDWORD, :SDWORD, :SDWORD, :SDWORD, :HWND, :HMENU, :HINSTANCE, :LPVOID
ShowWindow proto :HWND, :SDWORD
UpdateWindow proto :HWND
GetMessageA proto :ptr MSG, :HWND, :SDWORD, :SDWORD
TranslateMessage proto :ptr MSG
DispatchMessageA proto :ptr MSG
PostQuitMessage proto :SDWORD
DefWindowProcA proto :HWND, :UINT, :WPARAM, :LPARAM
;WinMain proto :HINSTANCE, :HINSTANCE, :LPSTR, :UINT
.data
ClassName db "SimpleWinClass",0
AppName db "Our First Window",0
.data?
hInstance HINSTANCE ?
CommandLine LPSTR ?
.code
WinMainCRTStartup proc FRAME
push rbp
.pushreg rbp
mov rbp,rsp
.setframe rbp, 0
.endprolog
sub rsp,32
mov ecx,NULL
call GetModuleHandleA
mov hInstance, rax
call GetCommandLineA
mov CommandLine, rax
mov rcx, hInstance
mov rdx, NULL
mov r8, CommandLine
mov r9d, SW_SHOWDEFAULT
call WinMain
mov ecx, eax
call ExitProcess
align 4
WinMainCRTStartup endp
WinMain proc FRAME
push rbp
.pushreg rbp
mov rbp,rsp
.setframe rbp, 0
.endprolog
sub rsp, sizeof WNDCLASSEXA + sizeof MSG + sizeof HWND + 12*8
hInst equ <[rbp+10h]>
hPrevInst equ <[rbp+18h]>
CmdLine equ <[rbp+20h]>
CmdShow equ <[rbp+28h]>
wc equ <[rbp - sizeof WNDCLASSEXA].WNDCLASSEXA>
msg equ <[rbp - sizeof WNDCLASSEXA - sizeof MSG].MSG>
hwnd equ <[rbp - sizeof WNDCLASSEXA - sizeof MSG - sizeof HWND]>
mov hInst, rcx ;store param1 in shadow space
mov wc.cbSize, SIZEOF WNDCLASSEXA
mov wc.style, CS_HREDRAW or CS_VREDRAW
; mov rax, OFFSET WndProc ;using LEA is preferable
lea rax, [WndProc]
mov wc.lpfnWndProc, rax
mov wc.cbClsExtra, NULL
mov wc.cbWndExtra, NULL
mov wc.hInstance, rcx
mov wc.hbrBackground, COLOR_WINDOW+1
mov wc.lpszMenuName, NULL
; mov rax, OFFSET ClassName ;using LEA is preferable
lea rax, [ClassName]
mov wc.lpszClassName, rax
mov ecx, NULL
mov edx, IDI_APPLICATION
call LoadIconA
mov wc.hIcon, rax
mov wc.hIconSm, rax
mov ecx, NULL
mov edx, IDC_ARROW
call LoadCursorA
mov wc.hCursor,rax
lea rcx, wc
call RegisterClassExA
mov ecx, NULL
lea rdx, [ClassName]
lea r8, [AppName]
mov r9d, WS_OVERLAPPEDWINDOW
mov dword ptr [rsp+4*8], CW_USEDEFAULT
mov dword ptr [rsp+5*8], CW_USEDEFAULT
mov dword ptr [rsp+6*8], CW_USEDEFAULT
mov dword ptr [rsp+7*8], CW_USEDEFAULT
mov qword ptr [rsp+8*8], NULL
mov qword ptr [rsp+9*8], NULL
mov rax, hInst
mov [rsp+10*8], rax
mov qword ptr [rsp+11*8], NULL
call CreateWindowExA
mov hwnd,rax
mov rcx, hwnd
mov edx, SW_SHOWNORMAL
call ShowWindow
mov rcx, hwnd
call UpdateWindow
;--- message loop
@@:
lea rcx, msg
mov rdx, NULL
mov r8, 0
mov r9, 0
call GetMessageA
and rax, rax
jz @F
lea rcx, msg
call TranslateMessage
lea rcx, msg
call DispatchMessageA
jmp @B
@@:
mov rax, msg.wParam
add rsp, sizeof WNDCLASSEXA + sizeof MSG + sizeof HWND + 12*8
pop rbp
ret
align 4
WinMain endp
WndProc proc FRAME
sub rsp, 4*8
.allocstack 4*8
.endprolog
cmp edx, WM_DESTROY
jnz @F
mov ecx, NULL
call PostQuitMessage
xor rax,rax
jmp exit
@@:
call DefWindowProcA
exit:
add rsp, 4*8
ret
align 4
WndProc endp
end