I try to compile a very simple prog with ml64 and with the less déclarations as possible.
I can compile and link it but it doesn't work,Help !
OPTION DOTNAME
option casemap:none
; include temphls.inc
;OPTION PROLOGUE:rbpFramePrologue
;OPTION EPILOGUE:rbpFrameEpilogue
; ------------------------------------------
; import libraries for Windows API functions
; ------------------------------------------
includelib user32.lib
includelib kernel32.lib
;------------------------------------------------------------------------------------
.const
InitInstance PROTO :DWORD
ExitProcess PROTO :DWORD
GetModuleHandleA PROTO :QWORD
MessageBoxA PROTO :QWORD ,:QWORD ,:QWORD ,:DWORD
.data
hInstance QWORD 0
Saverdi QWORD 0
errorrdi db "Bad Value",0
Titre db "rien",0
.code
;start:
WinMainCRTStartup proc
;fastcall need stack space before call
;one qword for return adress of call
;
add rsp,-(8 + 10 * 8) ; - (align + shadow space)
mov Saverdi,rdi ;save rdi en data
push rdi
mov rdi,200
mov rcx,1
call InitInstance
pop rdi
cmp rdi,Saverdi ;wrong if an API function had been call by the proc
je noproblem
mov rdi,Saverdi
xor rcx,rcx
lea rdx,errorrdi
lea r8,Titre
mov r9d,0
call MessageBoxA
;invoke MessageBoxA,0,addr errorrdi,addr Titre,0;MB_OK
noproblem:
xor rcx,rcx
call ExitProcess
WinMainCRTStartup endp
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
InitInstance PROC FRAME init:DWORD
Local retour:QWORD
mov retour,1
xor rcx,rcx
call GetModuleHandleA
mov hInstance,rax
FindeInitInstance:
mov rax,retour
ret
.endprolog
InitInstance endp
;################################################################
end
ml64 is not that comfortable as jwasm:
OPTION DOTNAME
option casemap:none
includelib user32.lib
includelib kernel32.lib
InitInstance PROTO :DWORD
ExitProcess PROTO :DWORD
GetModuleHandleA PROTO :QWORD
MessageBoxA PROTO :QWORD ,:QWORD ,:QWORD ,:DWORD
.data?
hInstance QWORD ?
.const
errorrdi db "Bad Value",0
Titre db "rien",0
.code
WinMainCRTStartup proc FRAME
push rdi
.pushreg rdi
sub rsp,4*8
.allocstack 4*8
.endprolog
mov rcx,1
call InitInstance
test rax,rax
je noproblem
xor rcx,rcx
lea rdx,errorrdi
lea r8,Titre
mov r9d,0
call MessageBoxA
noproblem:
xor eax,eax
add rsp,4*8
pop rdi
ret 0
WinMainCRTStartup endp
InitInstance PROC FRAME init:DWORD
Local retour:QWORD
push rbp
.pushreg rbp
mov rbp,rsp
.setframe rbp,0
sub rsp,6*8 ; shadow space + "retour"
.allocstack 6*8
.endprolog
mov retour,rcx
xor rcx,rcx
call GetModuleHandleA
mov hInstance,rax
mov rax,retour
add rsp,6*8
pop rbp
ret 0
InitInstance endp
end
These FRAME stuff could be omitted, if exception handling is not used.
Thanks.
All that trouble to verify that jwasm had a problem.
If you want you can verify that rdi is modify by jwasm.
Quote from: ToutEnMasm on August 27, 2015, 03:07:28 AM
If you want you can verify that rdi is modify by jwasm.
It's your move.
I test the following source code with ml64 and he did not a faut on rdi.
But there is something i don't understand.
If i delet the push edi and the pop edi in the prologue and epilogue,It's not accepted,by the messagebox who say ,it"s good "no problem:"why ???
OPTION DOTNAME
option casemap:none
includelib user32.lib
includelib kernel32.lib
InitInstance PROTO :DWORD
ExitProcess PROTO :DWORD
GetModuleHandleA PROTO :QWORD
MessageBoxA PROTO :QWORD ,:QWORD ,:QWORD ,:DWORD
.data
hInstance QWORD 0
errorrdi db "Bad Value",0
okrdi db "rdi correct",0
saverdi dq 0
Titre db "rien",0
.const
.code
InitInstance PROC FRAME init:DWORD
Local retour:QWORD
push rbp
.pushreg rbp
mov rbp,rsp
.setframe rbp,0
sub rsp,6*8 ; shadow space + "retour"
.allocstack 6*8
.endprolog
mov retour,rcx
xor rcx,rcx
call GetModuleHandleA
mov hInstance,rax
mov rax,retour
add rsp,6*8
pop rbp
ret 0
InitInstance endp
WinMainCRTStartup proc FRAME
sub rsp,4*8
.allocstack 4*8
push rdi ;not accepted to delet the line
.pushreg rdi ;not accepted to delet the line
.endprolog
mov saverdi,rdi
push rdi
;sub rsp,8
mov rcx,1
call InitInstance
pop rdi
;add rsp,8
cmp rdi,saverdi ;correct result here
je noproblem
xor rcx,rcx
lea rdx,errorrdi
lea r8,Titre
mov r9d,0
call MessageBoxA
jmp neutre
noproblem:
xor rcx,rcx
lea rdx,okrdi
lea r8,Titre
mov r9d,0
call MessageBoxA
neutre:
xor eax,eax
pop rdi ;not accepted to delet the line
add rsp,4*8
call ExitProcess ;
WinMainCRTStartup endp
end
Quote from: ToutEnMasm on August 27, 2015, 04:53:17 AMIf i delet the push edi and the pop edi in the prologue and epilogue,It's not accepted,why ???
because the shadow space must be aligned to 16 when calling a fastcall function (in other words: the memory block holding the stack parameters is aligned to 16). When entering a fastcall function the stack is misaligned by 8 (due to the pushed return address) thus you must allover allocate n*8 Bytes with odd n if you want call further fc functions.
You should take a look at these articles: x64 Software Conventions (http://msdn.microsoft.com/en-us/library/ms235286.aspx#)
Thanks.
Is it possible that a single push Inside a proc create a defaut alignment of the stack
and create problems ?
Quote from: ToutEnMasm on August 27, 2015, 05:16:56 AMIs it possible that a single push Inside a proc create a defaut alignment of the stack
and create problems ?
maybe yes, maybe no ... depends how you use the stack. What matters is that how the stack look before the calling a fc function.
Just for example, when using jWasm with the option WIN64 "INVOKE Stack Space Reservation [bit 1]: " push/pop can not used across invokes (see doc.).
must be this part
Quote
3.9 Directive OPTION WIN64
Directive OPTION WIN64 allows to set parameters for the Win64 output format if this format (see -win64 cmdline option) is selected. For other output formats, this option has no effect. The syntax for the directive is:
OPTION WIN64: switches
accepted values for switches are:
Store Register Arguments [ bit 0 ]:
- 0: the "home locations" (also sometimes called "shadow space") of the first 4 register parameters are uninitialized. This is the default setting.
- 1: register contents of the PROC's first 4 parameters (RCX, RDX, R8 and R9 ) will be copied to the "home locations" within a PROC's prologue.
INVOKE Stack Space Reservation [bit 1]:
- 0: for each INVOKE the stack is adjusted to reserve space for the parameters required for the call. After the call, the space is released again. This is the default setting.
- 1: the maximum stack space required by all INVOKEs inside a procedure is computed by the assembler and reserved once on the procedure's entry. It's released when the procedure is exited. If INVOKEs are to be used outside of procedures, the stack space has to be reserved manually!
Note: an assembly time variable, @ReservedStack, is created internally when this option is set. It will reflect the value computed by the assembler. It should also be mentioned that when this option is on, and a procedure contains no INVOKEs at all, then nevertheless the minimal amount of 4*8 bytes is reserved on the stack.
Warning: You should have understood exactly what this option does BEFORE you're using it. Using PUSH/POP instruction pairs to "save" values across an INVOKE is VERBOTEN if this option is on.
-------------------------------------------------------------------------------------------------------------------------
Warning: You should have understood exactly what this option does BEFORE you're using it. Using PUSH/POP instruction pairs to "save" values across an INVOKE is VERBOTEN if this option is on.
-------------------------------------------------------------------------------------------------------------------------
The doc seem to explain this ( option WIN64 is on)
include sdk64.inc
.const
Verboten PROTO
.data
hInstance QWORD 0
Saverdi QWORD 0
errorrdi db "Bad Value",0
Titre db "rien",0
RelativePath db MAX_PATH dup (0)
.code
Start:
;fastcall need stack space before call
;one qword for return adress of call
;
add rsp,-(8 + 4 * 8) ; - (align + shadow space)
invoke Verboten
;invoke DebugBreak
invoke ExitProcess,0
;@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@
InitInstance PROC FRAME init:DWORD
Local retour:QWORD,rien:qword
mov retour,1
.if init == 1
xor rcx,rcx
invoke GetModuleHandle,NULL
mov hInstance,rax
;--------------------------------------------------------------
invoke GetModuleFileName,hInstance,addr RelativePath,sizeof RelativePath
.endif
FindeInitInstance:
mov rax,retour
ret
InitInstance endp
;################################################################
Verboten PROC FRAME
Local retour:DWORD
mov retour,1
mov Saverdi,rdi ;save rdi en data
push rdi ;<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<< VERBOTEN
mov rdi,200
mov rcx,1
call InitInstance
pop rdi
.if rdi != Saverdi ;wrong if an API function had been call by the proc
mov rdi,Saverdi
invoke MessageBox,0,addr errorrdi,addr Titre,0;MB_OK
.endif
FindeVerboten:
mov eax,retour
ret
Verboten endp
;################################################################
end Start
Bonjour, Yves!
include win64a.inc
.data
hInstance dq ?
Saverdi dq ?
errorrdi db "Bad Value",0
Titre db "rien",0
RelativePath db MAX_PATH dup (0)
.code
WinMain proc
local retour:QWORD
push rbp
mov ebp,esp
sub esp,(8+15)and(-16)
mov retour,1
mov Saverdi,rdi ;save rdi en data
push rdi ;<-- align rsp 10h
push rdi
mov rdi,200
mov ecx,1
call InitInstance
pop rdi
pop rdi
cmp rdi,Saverdi ;wrong if an API function had been call by the proc
je FindeVerboten
mov rdi,Saverdi
xor r9d,r9d;MB_OK
mov r8d,offset Titre
mov edx,offset errorrdi
xor ecx,ecx
call MessageBox
FindeVerboten:
mov rax,retour
xor ecx,ecx
call ExitProcess
WinMain endp
InitInstance PROC init:QWORD
local retour:QWORD
local rien:qword
push rbp
mov ebp,esp
sub esp,(20h+2*8+15)and(-16)
mov init,rcx
mov retour,1
.if init == 1
xor ecx,ecx
call GetModuleHandle
mov hInstance,rax
;--------------------------------------------------------------
mov r8d,sizeof RelativePath
mov edx,offset RelativePath
mov ecx,eax;hInstance
call GetModuleFileName
.endif
FindeInitInstance:
mov rax,retour
leave
ret
InitInstance endp
end