I have kept working on trying to get a basic window that looks more like conventional API code. It would seem that any procedure that has more than 4 arguments needs to have a stack frame. Those with less arguments appear to work fine with no stack frame as do pure mnemonic procedures. Something I found unusual was that I could not get a clean exit with the window unless I specifically used SendMessage to WM_DESTROY from the WM_CLOSE message location.
This is the test piece.
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
OPTION DOTNAME
option casemap:none
include \masm64\include\temphls.inc
include \masm64\include\win64.inc
include \masm64\include\kernel32.inc
include \masm64\include\user32.inc
include \masm64\include\msvcrt.inc
includelib \masm64\lib\kernel32.lib
includelib \masm64\lib\user32.lib
includelib \masm64\lib\msvcrt.lib
OPTION PROLOGUE:rbpFramePrologue
OPTION EPILOGUE:rbpFrameEpilogue
include macros64.inc
WNDCLASSEX64 STRUCT QWORD
cbSize dd ?
style dd ?
lpfnWndProc dq ?
cbClsExtra dd ?
cbWndExtra dd ?
hInstance dq ?
hIcon dq ?
hCursor dq ?
hbrBackground dq ?
lpszMenuName dq ?
lpszClassName dq ?
hIconSm dq ?
WNDCLASSEX64 ENDS
.data
ClassName db "API Window Class",0
AppName db "Bare API Window",0
.data?
hInstance dq ?
hWnd dq ?
sWid dq ?
sHgt dq ?
lft dq ?
top dq ?
wid dq ?
hgt dq ?
.code
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
main proc
LOCAL wcex:WNDCLASSEX64
mov hInstance, rv64(GetModuleHandle,0)
mov wcex.cbSize, SIZEOF WNDCLASSEX64
mov wcex.style, 0
mov rax, OFFSET WndProc
mov wcex.lpfnWndProc, rax
mov wcex.cbClsExtra, 0
mov wcex.cbWndExtra, 0
mov rax, hInstance
mov wcex.hInstance, rax
mov wcex.hIcon, 10003h
mov wcex.hCursor, 10003h
mov wcex.hbrBackground, COLOR_WINDOW
mov wcex.lpszMenuName, 0
mov rax, OFFSET ClassName
mov wcex.lpszClassName, rax
mov wcex.hIconSm, 10003h
invoke RegisterClassEx, ADDR wcex
invoke GetSystemMetrics,SM_CXSCREEN
mov r11, rax
shr rax, 2
mov lft, rax
mov rax, r11
shr rax, 1
mov wid, rax
invoke GetSystemMetrics,SM_CYSCREEN
mov r11, rax
shr rax, 2
mov top, rax
mov rax, r11
shr rax, 1
mov hgt, rax
invoke CreateWindowEx,0,addr ClassName,addr AppName,\
WS_OVERLAPPEDWINDOW or WS_VISIBLE,\
lft,top,wid,hgt,0,0,hInstance,0
mov hWnd, rax
call msgloop
invoke ExitProcess, rax
main endp
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
msgloop proc
LOCAL msg :MSG
mov r11, rdi ; preserve rdi
lea rdi, msg ; load structure address
jmp gmsg
@@:
fn64 TranslateMessage,rdi
fn64 DispatchMessage,rdi
gmsg:
fn64 GetMessage,rdi,0,0,0
test rax, rax
jnz @B
mov rdi, r11 ; restore rdi
fn64 ExitProcess, 0
retn
msgloop endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
WndProc proc
LOCAL64 hWin
LOCAL64 uMsg
LOCAL64 wParam
LOCAL64 lParam
mov hWin, rcx
mov uMsg, rdx
mov wParam, r8
mov lParam, r9
.if uMsg == WM_COMMAND
.elseif uMsg == WM_CLOSE
.data
text db "Seeya round like a Rubens",0
titl db "WM_CLOSE here",0
ptxt dq text
pttl dq titl
.code
fn64 MessageBox,0,ptxt,pttl,0
fn64 SendMessage,hWin,WM_DESTROY,0,0
.elseif uMsg == WM_DESTROY
fn64 PostQuitMessage,NULL
.endif
fn64 DefWindowProc,hWin,uMsg,wParam,lParam
retn
WndProc endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
; ¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤¤
end
; ----------
; left overs
; ----------
; .elseif uMsg == WM_SYSCOMMAND
; .if wParam == SC_CLOSE
; fn64 SendMessage,wHandle,WM_DESTROY,0,0
; .endif
; fn64 SendMessage,wHandle,WM_SYSCOMMAND,SC_CLOSE,NULL
You seem to allocate spill space, call GetModuleHandle then reclaim that space, leaving none for the other API calls.
Maybe you're lucky with the spill being absorbed by the locals?
no cigar :(
Microsoft (R) Macro Assembler Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: window2.asm
\masm64\include\temphls.inc(86) : error A2008:syntax error : retn
\masm64\include\temphls.inc(87) : error A2008:syntax error : MACRO
\masm64\include\temphls.inc(91) : error A2034:must be in segment block
\masm64\include\temphls.inc(92) : error A2034:must be in segment block
\masm64\include\temphls.inc(94) : fatal error A1008:unmatched macro nesting
Microsoft (R) Incremental Linker Version 10.00.30319.01
The problem is the documentation is so poor that I am writing this stuff by test piece to see what will actually run.
JJ,
These are the assembler and linker I am using. It looks like you are using the 32 bit version of ML.
Microsoft (R) Macro Assembler (x64) Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Assembling: window2.asm
Microsoft (R) Incremental Linker Version 10.00.30319.01
Copyright (C) Microsoft Corporation. All rights reserved.
Volume in drive K is disk3_k
Volume Serial Number is 68C7-4DBB
Directory of K:\asm64\window2
07/02/2016 12:09 AM 4,096 window2.exe
1 File(s) 4,096 bytes
0 Dir(s) 990,489,694,208 bytes free
This is the batch file I am building it with.
@echo off
\masm64\bin\ml64.exe /c window2.asm
\masm64\bin\link.exe /SUBSYSTEM:WINDOWS /ENTRY:main /LARGEADDRESSAWARE window2.obj
dir window2.exe
pause
sinsi,
It works just as well with the following. I think its Vasily's macros providing the spill space.
;;; mov hInstance, rv64(GetModuleHandle,0)
invoke GetModuleHandle,0
mov hInstance, rax
This is what the proc entry and API disassemble to.
0x00000001`40001000: C8900000 enter 0x90,0x0
0x00000001`40001004: 33C9 xor ecx,ecx
0x00000001`40001006: FF15FC0F0000 call qword ptr [kernel32.dll!GetModuleHandleA]
0x00000001`4000100C: 4889056D200000 mov qword ptr [0x0000000140003080],rax
Quote from: hutch-- on July 02, 2016, 12:07:12 AM
These are the assembler and linker I am using. It looks like you are using the 32 bit version of ML.
Microsoft (R) Macro Assembler (x64) Version 10.00.30319.01
That could indeed explain something. Mine sits in C:\Program Files (
x86)\Microsoft Visual Studio 10.0\VC\bin\ml.exe
I didn't know that there are separate 32- and 64-bit versions of VS :(
I'm using ver 12 which is 64-bit, came from vs13 iirc.
Microsoft (R) Macro Assembler Version 12.00.31101.0
Hutch,
Thanks a lot, now I could build (and debug) my first 64-bit program :t
I feel a bit uneasy about Vasily's libs, includes and macros, though. Once adopted, they will effectively block the road for the Watcom family assemblers, the main reason being that it contains workarounds for the crippled ML64. And he is not a particularly active member of our forum, too.
OTOH the other assemblers seem to drift apart a little bit, and I can't imagine following (macro-wise, commandline option-wise) several idiosyncratic forks. It was a lot of work to keep my baby (http://www.webalice.it/jj2006/MasmBasicQuickReference.htm) compatible to ML 6.15...10.0, JWasm, AsmC ::)
I don't want to spoil the party here, especially because I don't plan to become an active 64-bit fan. Playing around, yes, real work, no :lol:
The good news is we are beyond the last remark:
Quote from: jj2007 on June 24, 2016, 01:11:22 AMIt might be helpful to have a sticky post in the 64-bit forum with a "Hello World" archive containing
- basic includes (kernel, user, msvcrt, ...), or at least exact links to them
- basic libs, or at least exact links to them
- a batch file that takes an asm file as argument
- a link to the version of ml/jwasm/hjwasm/asmc that works with the hello world
- a link to a free 64-bit debugger
So far, I find it far too confusing to even start playing with 64-bit code 8)
But it would still require work and discipline to arrive at a "starter's kit for 64-bit assembly" that is as easy to use and consistent as the Masm32 libraries and includes.
P.S.: Window 3 builds, but only without resources:
QuoteImpossibile avviare il programma perché api-ms-win-crt-runtime-l1-1-0.dll non è presente nel computer. Per risolvere il problema, provare a reinstallare il programma.
That it's in Italian is part of the problem: No help from the internet... Microsoft crap, DLL hell version 2.0.
Impossibile avviare il programma perché api-ms-win-crt-runtime-l1-1-0.dll non è presente nel computer. Per risolvere il problema, provare a reinstallare il programma.
Google translate
Unable to start the program because bee-ms-win-crt-runtime-l1-1-0.dll is not on the computer. To solve the problem, try reinstalling the program
Does the version with resources and manifest run OK ?
Your exe runs ok. It's cvtres that complains... edit: ok after installing Visual C++ Redistributable for Visual Studio 2015 (https://www.microsoft.com/en-us/download/details.aspx?id=48145)
Quote from: jj2007 on July 03, 2016, 02:01:44 AM
But it would still require work and discipline to arrive at a "starter's kit for 64-bit assembly" that is as easy to use and consistent as the Masm32 libraries and includes.
that may, just possibly, be true. Perhaps.
@hutch good pun "authodox" = authorized orthodox
:biggrin:
Too many years of being assaulted by American spell checkers in browsers. :P