This example is lousy as it is for poasm, hjwasm and ml64.
ml64 is the weakest link.
Any ideas to make it better?
option casemap:none
option epilogue:none
option prologue:none
ifdef __POASM__
ret equ retn
extern WndProc : proc
endif
ifdef __HJWASM__
;option stackbase:rsp
endif
extern ExitProcess : proc
extern GetModuleHandleA : proc
extern MessageBoxA : proc
extern LoadCursorA : proc
extern LoadIconA : proc
extern RegisterClassExA : proc
extern CreateWindowExA : proc
extern DefWindowProcA : proc
extern ShowWindow : proc
extern GetMessageA : proc
extern TranslateMessage : proc
extern DispatchMessageA : proc
extern PostQuitMessage : proc
extern DestroyWindow : proc
WNDCLASSEX struct
cbSize dd ?
style dd ?
lpfnWndProc dq ?
cbClsExtra dd ?
cbWndExtra dd ?
hInstance dq ?
hIcon dq ?
hCursor dq ?
hbrBackground dq ?
lpszMenuName dq ?
lpszClassName dq ?
hIconSm dq ?
WNDCLASSEX ends
POINT struct
x dd ?
y dd ?
POINT ends
MSG struct
hwnd dq ?
message dd ?
padding1 dd ? ; padding
wParam dq ?
lParam dq ?
time dd ?
pt POINT <>
padding2 dd ? ; padding
MSG ends
.const
NULL equ 0
CS_VREDRAW equ 1
CS_HREDRAW equ 2
COLOR_WINDOW equ 5
; WS_OVERLAPPEDWINDOW = (WS_OVERLAPPED | WS_CAPTION | WS_SYSMENU | WS_THICKFRAME | WS_MINIMIZEBOX | WS_MAXIMIZEBOX)
WS_OVERLAPPEDWINDOW equ 0CF0000h
CW_USEDEFAULT equ 80000000h
IDI_APPLICATION equ 7F00h
IDC_ARROW equ 7F00h
SW_SHOW equ 5
WM_DESTROY equ 2
WM_COMMAND equ 111h
IDC_MENU equ 2001
IDM_EXIT equ 6001
IDM_ABOUT equ 6002
.data
szWindowClass db 'FirstApp', 0
szTitle db 'My First x64 Windows', 0
szHelpTitle db 'Help', 0
szHelpText db 'This will be a big help...', 0
.data?
;hInstance qword ?
;hWnd qword ?
.code
WinMainCRTStartup proc
sub rsp, 28h
xor ecx, ecx
call GetModuleHandleA
mov rcx, rax
; mov [rip + hInst], rax
mov r9d, 5
xor r8, r8
xor edx, edx
call WinMain
mov ecx, eax
call ExitProcess
WinMainCRTStartup endp
WinMain proc
sub rsp,58h
mov qword ptr [rsp+58h+8h],rcx ; hInstance
mov r8, offset WndProc
mov rdx, offset szWindowClass
call InitClass
cmp eax,0
je @end
mov r8, offset szTitle
mov rdx, offset szWindowClass
mov rcx,qword ptr [rsp+58h+8h] ; hInstance
call InitWindow
cmp rax,0
jne @F
mov eax,0
jmp @end
@@:
mov edx,1
mov rcx, rax
call ShowWindow
lea rdi,[rsp+20h]
@msgloop:
xor r9d,r9d
xor r8d,r8d
xor edx,edx
mov rcx, rdi
call GetMessageA
cmp eax,0
je @done
mov rcx, rdi
call TranslateMessage
mov rcx, rdi
call DispatchMessageA
jmp @msgloop
@done:
mov eax,dword ptr [rsp+30h] ; msg.wParam
@end:
add rsp,58h
ret
WinMain endp
WndProc proc hWnd : qword, uMsg : dword, wParam : qword, lParam : qword
; mov [rsp+8], rcx ; hWnd (save parameters as locals)
; mov [rsp+10h], edx ; Msg
; mov [rsp+18h], r8 ; wParam
; mov [rsp+20h], r9 ; lParam
sub rsp, 38h
cmp edx, WM_COMMAND
jnz @F
call WMCommand
jmp @end ; break
@@:
cmp edx, WM_DESTROY
jnz @F
call WMDestroy
xor eax, eax
jmp @end
@@:
@default:
; mov r9, [rsp+38h+20h] ; lParam
; mov r8, [rsp+38h+18h] ; wParam
; mov edx, [rsp+38h+10h] ; Msg
; mov rcx, [rsp+38h+8] ; hWnd
call DefWindowProcA
@end:
add rsp, 38h
ret
WndProc endp
InitClass proc hInst:qword, lpClass:qword, lpWndProc:qword
sub rsp, 78h ; space for WNDCLASSEX
lea r10,[rsp+20h]
mov [r10].WNDCLASSEX.hInstance, rcx ; hInst
mov [r10].WNDCLASSEX.lpszClassName, rdx ; lpClass
mov [r10].WNDCLASSEX.lpfnWndProc, r8 ; lpWndProc
mov [r10].WNDCLASSEX.cbSize, sizeof WNDCLASSEX
mov [r10].WNDCLASSEX.style, CS_VREDRAW or CS_HREDRAW
xor eax, eax
mov [r10].WNDCLASSEX.cbClsExtra, eax
mov [r10].WNDCLASSEX.cbWndExtra, eax
mov [r10].WNDCLASSEX.hbrBackground, COLOR_WINDOW
mov [r10].WNDCLASSEX.lpszMenuName, IDC_MENU
xor ecx, ecx
mov edx, IDI_APPLICATION
call LoadIconA
lea r10,[rsp+20h] ;
mov [r10].WNDCLASSEX.hIcon, rax
mov [r10].WNDCLASSEX.hIconSm, rax
xor ecx, ecx
mov edx, IDC_ARROW
call LoadCursorA
lea r10,[rsp+20h]
mov [r10].WNDCLASSEX.hCursor, rax
mov rcx, r10
call RegisterClassExA
add rsp, 78h
ret
InitClass endp
InitWindow proc hInst:qword, lpClass:qword, lpApp:qword
sub rsp, 68h ; space for parameters
xor rax, rax
mov [rsp+58h], rax ; lpParam
mov [rsp+50h], rcx ; hInstance
mov [rsp+48h], rax ; hMenu = NULL
mov [rsp+40h], rax ; hWndParent = NULL
mov [rsp+38h], rax ; Height
mov [rsp+28h], rax ; Y
mov rax, CW_USEDEFAULT
mov [rsp+30h], rax ; Width
mov [rsp+20h], rax ; X
mov r9d, WS_OVERLAPPEDWINDOW ; dwStyle
; mov r8, offset szTitle ; lpWindowName
; mov rdx, offset szWindowClass ; lpClassName
xor ecx, ecx ; dwExStyle
call CreateWindowExA
add rsp,68h
ret
InitWindow endp
WMCommand proc hWnd : qword, uMsg : dword, wParam : qword, lParam : qword
sub rsp, 28h
cmp r8w, IDM_ABOUT
jz @about
cmp r8w, IDM_EXIT
jz @exit
@about:
xor r9d, r9d
; lea r8, szHelpTitle
mov r8, offset szHelpTitle
; lea rdx, szHelpText
mov rdx, offset szHelpText
xor ecx, ecx
call MessageBoxA
jmp @end
@exit:
call DestroyWindow
xor rax, rax
jmp @end
@end:
xor eax,eax
add rsp,28h
ret
WMCommand endp
WMDestroy proc hWnd : qword, uMsg : dword, wParam : qword, lParam : qword
sub rsp, 28h
; INVOKE PostQuitMessage,NULL
xor ecx, ecx ; exit code
call PostQuitMessage
xor eax,eax
add rsp,28h
ret
WMDestroy endp
end
#include <windows.h>
LANGUAGE LANG_ENGLISH,SUBLANG_ENGLISH_US
2001 MENUEX
{
POPUP "File", 0, 0, 0
{
MENUITEM "About", 6002, 0, 0
MENUITEM "&Exit", 6001, 0, 0
}
}
EDIT fixed some bugs.
more fixes.