It's a special window usinng the crt in 64 bits
There is the good and the bad source code.
The good work.
The bad just move a line from 54 to 72
"invoke sprintf_s,addr szbuffer,sizeof szbuffer,addr format,reel"
The bad made an access violation after the ret.
Try many things to find from what it came but didn't found.
Only one solution i found is to expand the function:
"invoke sprintf_s,addr szbuffer,sizeof szbuffer,addr format,reel"
to:
Quote
mov r9,qword ptr [reel]
lea rcx,szbuffer
mov edx,80h
lea r8,format
call sprintf_s
and all is good
disasm of the good(call) and bad(invoke)
Quote
;------------- dumpbin /DISASM -----------------------------------
;first sprintf_s is the good,second is the invoke bad
0000000140001325: 4C 8B 0D 18 5D 00 mov r9,qword ptr [140007044h]
00
000000014000132C: 4C 8D 05 1D 5D 00 lea r8,[140007050h]
00
0000000140001333: BA 80 00 00 00 mov edx,80h
0000000140001338: 48 8D 0D 1E 5D 00 lea rcx,[14000705Dh]
00
000000014000133F: E8 DC 0B 00 00 call sprintf_s
0000000140001344: 4C 8B 0D F9 5C 00 mov r9,qword ptr [140007044h]
00
000000014000134B: 48 8D 0D 0B 5D 00 lea rcx,[14000705Dh]
00
0000000140001352: BA 80 00 00 00 mov edx,80h
0000000140001357: 4C 8D 05 F2 5C 00 lea r8,[140007050h]
00
000000014000135E: E8 BD 0B 00 00 call sprintf_s
;--------------- objconv ------------------------------------
; Note: Memory operand is misaligned. Performance penalty
mov r9, qword ptr [?_357] ; 40001325 _ 4C: 8B. 0D, 00005D18(rel)
lea r8, [?_358] ; 4000132C _ 4C: 8D. 05, 00005D1D(rel)
mov edx, 128 ; 40001333 _ BA, 00000080
lea rcx, [?_359] ; 40001338 _ 48: 8D. 0D, 00005D1E(rel)
call ?_060 ; 4000133F _ E8, 00000BDC
; Note: Memory operand is misaligned. Performance penalty
mov r9, qword ptr [?_357] ; 40001344 _ 4C: 8B. 0D, 00005CF9(rel)
lea rcx, [?_359] ; 4000134B _ 48: 8D. 0D, 00005D0B(rel)
mov edx, 128 ; 40001352 _ BA, 00000080
lea r8, [?_358] ; 40001357 _ 4C: 8D. 05, 00005CF2(rel)
call ?_060 ; 4000135E _ E8, 00000BBD
Unfortunately when I try to run your .exe it complains that some visual studio file is missing.
Various things here don't make sense. In the "good" and "bad" disassemblies why are the orders of the arguments different? In "good" they're r9, r8, edx, rcx (which makes sense) but in "bad" they're r9, rcx, edx, r8. Obviously should be immaterial, but why is this?
I notice the disassembled instructions are different, for instance,
mov r9,qword ptr [140007044h]
is "4C 8B 0D 18 5D 00" in "good", but "4C 8B 0D F9 5C 00" in "bad". And, it can't be explained (as far as I can tell) by use of RIP. So, what's that about?
And, I'm surprised it used edx instead of rdx. Again, should make no difference, but ... ?
Must admit it looks like a bug in JWasm but hard to believe, since I've used JWasm invoke many times with no trouble, including with sprintf. So, since your environment is different, maybe that's causing the problem. If I were to go to the trouble of getting your source working in my environment (without Visual Studio) it would probably work right.
Also, I bet if you used my nvk macro (http://masm32.com/board/index.php?topic=3988.0) it would work correctly.
One other thought, instead of simply "ret" at the end try "invoke ExitProcess, 0" - because, if I understood u correctly, u said the problem only occurs after the program exits
Interesting work
As test,Ihave made some modifies:
added the msvcrt.lib (Windows 10 new crt)
added the sprintf_s function in the WM_CREATE message
called in loop (100) with nvk macro,no problem.
called in loop (100) with invoke, ------------------------ Failed ------------------
Unfortunately I don't have sprintf_s in the .inc files from WinInc. But I tried it with sprintf, that worked. Are you sure rsp is aligned when you invoke sprintf_s? For nvk, it doesn't have to be aligned, therefore this sample doesn't use "and rsp, -16"
nvk, BTW, always works, in many situations where invoke doesn't. In addition to alignment invoke can't use certain registers such as rcx, and there may be other problems, I don't know. I always get my prog working with nvk, then replace them with invoke as appropriate. nvk uses more code than invoke, so especially when it's in a macro that gets repeated, build size can be considerably reduced with invoke. But fairly often invoke fails, so I just leave nvk there. Perhaps you could use that strategy also
You don't need the include file to use the function.
The declaration and the lib are enough.
Quote
sprintf_s PROTO fastcall :QWORD ,:DWORD ,:QWORD , :VARARG
Here the modify sample I posted upper using your invoke macro,it work.
just use the sdk64_simple.inc instead of the sdk64.inc.
Other include are here:
http://masm32.com/board/index.php?topic=563.msg4563#msg4563
I made various tests with various invoke macro.
Here is one,who don't solve my problem,extracted from here:
http://masm32.com/board/index.php?topic=4536.msg48608#msg48608
I know that the forum had many other one,i hope for 64 bits.
If you find one put it here.
There are lost in the numerous posts and hard to find.
Quote from: ToutEnMasmYou don't need the include file to use the function. The declaration and the lib are enough.
- I wasn't clear. I meant, my msvcrt.lib doesn't seem to have sprint_s. Using either your proto, or my own include files (which don't specify fastcall) which as I remember came from Wininc, it says it can't find the function. Dunno why
Prologue and epilogue are modified by the use of invoke
bad with invoke
Quote
WindProc:
0000000140001410: 48 89 4C 24 08 mov qword ptr [rsp+8],rcx
0000000140001415: 48 89 54 24 10 mov qword ptr [rsp+10h],rdx
000000014000141A: 4C 89 44 24 18 mov qword ptr [rsp+18h],r8
000000014000141F: 4C 89 4C 24 20 mov qword ptr [rsp+20h],r9
0000000140001424: 48 83 EC 38 sub rsp,38h
;-------
0000000140001633: 48 83 C4 38 add rsp,38h
0000000140001637: C3 ret
good
Quote
0000000140001410: 48 89 4C 24 08 mov qword ptr [rsp+8],rcx
0000000140001415: 48 89 54 24 10 mov qword ptr [rsp+10h],rdx
000000014000141A: 4C 89 44 24 18 mov qword ptr [rsp+18h],r8
000000014000141F: 4C 89 4C 24 20 mov qword ptr [rsp+20h],r9
0000000140001424: 48 83 EC 78 sub rsp,78h ;<<<<<<<<<<<<<<<<<<<<<<<<<<
;-----------------------------------------------------------------
0000000140001660: 48 83 C4 78 add rsp,78h
0000000140001664: C3 ret
Here the proof it's a problem of prologue and epilogue
use :
OPTION PROLOGUE:NONE
OPTION EPILOGUE:NONE
;-------------- build prologue ------------------------------------------------------------------
WindProc PROC hwnd:HWND,uMsg:UINT,wParam: WPARAM, lParam:LPARAM
LOCAL retour:QWORD,child:HWND,Hfen:HWND
sub rsp,78h
mov hwnd,rcx
mov uMsg,edx
mov wParam,r8
mov lParam,r9
;-------------- build epilogue ------------------------------------------------------------------
add rsp,78h
ret
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
and "invoke sprintf_s,addr szbuffer,sizeof szbuffer,addr format,reel" can be used without problem
include sdk64.inc
;include stdio.sdk
;include invoke_macros.inc
;include ml64_invoke.txt
;include temphls.inc
;stdlib.sdk
;include prologue.txt
includelib msvcrt.lib ;load ucrt.lib,vcruntime.lib
wprintf PROTO cproto :XMASM , :VARARG
sprintf_s PROTO :QWORD ,:DWORD ,:QWORD , :VARARG
.const
RtlZeroMemory PROTO :XMASM,:DWORD
_invalid_parameter PROTO :XMASM ,:XMASM ,:XMASM ,:DWORD ,:DWORD
MAKEBUG equ
;-------------------------------------------------------------------------------------------------------------
.data
fenetre db "fenetre"
fentitre db "Fenêtre sans focus",0
button db "button",0
edit db "EDIT",0
beep db "Beep",0
son1 db "Son 1",0
son2 db "Son 2",0
son3 db "Son 3",0
Fermer db "Fermer",0
reel REAL8 33.43375412889645
format db "Reel: %.9f",13,10,0
szbuffer db 80h dup (0)
titre db "Titre",0
chainenull db "NULL",0
invalid db "Argument invalide",0
crttitre db "CRT",0
.data?
hBeep HANDLE ?
hSon1 HANDLE ?
hSon2 HANDLE ?
hSon3 HANDLE ?
hFermer HANDLE ?
font HANDLE ?
Hedit HANDLE ?
Hinstance HANDLE ?
garderegister qword ?
.code
;OPTION PROLOGUE:StdPrologue ;rbpFramePrologue
;OPTION EPILOGUE:StdEpilogue ;rbpFrameEpilogue
;OPTION PROLOGUE:NONE
;OPTION EPILOGUE:NONE
_invalid_parameter PROC FRAME expression:XMASM,function:XMASM,file:XMASM,line:DWORD,pReserved:DWORD
Local retour:DWORD
mov retour,1
invoke MessageBox,NULL,ADDR invalid,addr crttitre,MB_OK
Findeinvalid_parameter:
mov eax,retour
ret
_invalid_parameter endp
.LISTALL
OPTION PROLOGUE:NONE ;rbpFramePrologue ;StdPrologue
OPTION EPILOGUE:NONE ;rbpFrameEpilogue ;StdEpilogue
WindProc PROC hwnd:HWND,uMsg:UINT,wParam: WPARAM, lParam:LPARAM
LOCAL retour:QWORD,child:HWND,Hfen:HWND
sub rsp,78h
mov hwnd,rcx
mov uMsg,edx
mov wParam,r8
mov lParam,r9
mov retour,0 ;the more common return value
.if uMsg == WM_CREATE
;Création des contrôles:
invoke CreateWindowEx,0,addr button,0,WS_CHILD or WS_VISIBLE or BS_GROUPBOX ,4,4,276,140,hwnd,0,0,0
invoke CreateWindowEx,0,addr button,addr beep,WS_CHILD or WS_VISIBLE ,20,20,100,20,hwnd,0,0,0
mov hBeep,rax
invoke CreateWindowEx,0,addr button,addr son1,WS_CHILD or WS_VISIBLE,20,50,100,20,hwnd,0,0,0
mov hSon1,rax
invoke CreateWindowEx,0,addr button,addr son2,WS_CHILD or WS_VISIBLE,20,80,100,20,hwnd,0,0,0
mov hSon2,rax
invoke CreateWindowEx,0,addr button,addr son3,WS_CHILD or WS_VISIBLE,20,110,100,20,hwnd,0,0,0
mov hSon3,rax
invoke CreateWindowEx,0,addr button,addr Fermer,WS_CHILD or WS_VISIBLE,160,70,100,20,hwnd,0,0,0
mov hFermer,rax
invoke CreateWindowEx,0,addr edit,addr chainenull,WS_CHILD or WS_VISIBLE,160,100,100,20,hwnd,0,Hinstance,0
mov Hedit,rax
;---------- jwasm bug--------------------------
;----------------------------------
mov r9, reel
lea rcx, szbuffer
mov edx, sizeof szbuffer
lea r8, format
call sprintf_s ;end good without invoke
;-----------------------------------
IFDEF MAKEBUG
ECHO BUG
invoke sprintf_s,addr szbuffer,sizeof szbuffer,addr format,reel
ELSE
ECHO NOP
REPEAT 31
NOP
ENDM
ENDIF
overbug:
;----- echoue bad ret-----------
; Changement de la police des contrôles:
invoke GetStockObject,DEFAULT_GUI_FONT
mov font,rax
mov child,0
loopfont:
invoke FindWindowEx,hwnd,child,0,0
mov child,rax
.if child != 0
invoke SendMessage,child,WM_SETFONT,font,0
jmp loopfont
.endif
invoke SendMessage,Hedit,WM_SETTEXT,0,addr szbuffer
.elseif uMsg == WM_CLOSE
invoke DestroyWindow,hwnd
.elseif uMsg == WM_DESTROY
invoke PostQuitMessage,NULL
.elseif uMsg == WM_COMMAND
mov r10,lParam
.if r10 == hFermer
invoke SendMessage,hwnd,WM_CLOSE,0,0
.elseif r10 == hBeep
invoke Beep,800,50
.elseif r10 == hSon1
invoke MessageBeep,MB_OK
.elseif r10 == hSon2
invoke MessageBeep,MB_ICONHAND
.elseif r10 == hSon3
invoke MessageBeep,MB_ICONEXCLAMATION
.endif
.else
invoke DefWindowProc,hwnd,uMsg,wParam,lParam
mov retour,rax
.endif
mov rax,retour
add rsp,78h
ret
WindProc endp
OPTION PROLOGUE:PrologueDef
OPTION EPILOGUE:EpilogueDef
.NOLIST
wWinMain PROC FRAME hinst:HINSTANCE , hprev:HINSTANCE , szcmd:LPSTR ,ishow:DWORD
LOCAL wc:WNDCLASSEX,msg:MSG
;---------------------------------------------------------
mov hinst,rcx
mov Hinstance,rcx
;-------------------------------------------------------------------------
invoke _set_invalid_parameter_handler,offset _invalid_parameter
;-------------------------------------------------------------------------
invoke RtlZeroMemory,addr wc,sizeof WNDCLASSEX
mov wc.cbSize,sizeof WNDCLASSEX
push hinst
pop wc.hInstance
mov rax,offset fenetre
mov wc.lpszClassName,rax
mov rax,WindProc
mov wc.lpfnWndProc,rax
invoke LoadCursor,0,IDC_ARROW
mov wc.hCursor,rax
invoke LoadIcon,0,IDI_APPLICATION
mov wc.hIcon,rax
invoke GetStockObject,LTGRAY_BRUSH
mov wc.hbrBackground,rax
;Enregistrement de notre classe de fenêtre:
invoke RegisterClassEx,addr wc
; Création de notre fenêtre:
; invoke DebugBreak
invoke CreateWindowEx,WS_EX_NOACTIVATE or WS_EX_TOOLWINDOW or WS_EX_TOPMOST,addr fenetre,\
addr fentitre,WS_VISIBLE or WS_POPUP or WS_DLGFRAME,20,20,290,160,0,0,hinst,0
;Boucle des uMsgs:
.if rax != 0
loopMessage:
invoke GetMessage,addr msg,0,0,0
.if eax == 1 ;success
invoke DispatchMessage,addr msg
invoke TranslateMessage,addr msg
jmp loopMessage
.endif
.endif
; Sortie du programme:
xor rax,rax
ret
wWinMain ENDP
end