Push an argument into stack?
I know that the first four arguments are in the register (RCX, RDX, R8, R9), and that additional arguments are pushed on the stack.
How to push an argument onto the stack? I tried with (push 0) but it does not work?
extrn ExitProcess: PROC extrn MessageBoxExA: PROC .data caption db '64-bit hello!', 0 message db 'Hello World!', 0 .code Start PROC sub rsp, 38h mov rcx, 0 ; hWnd = HWND_DESKTOP lea rdx, message ; LPCSTR lpText lea r8, caption ; LPCSTR lpCaption mov r9d, 0 ; uType = MB_OK push 0 ; wLanguageId call MessageBoxExA mov ecx, eax add rsp, 38h call ExitProcess Start ENDP End
I'm know that MessageBox and MessageBoxEx work the same way, but im trying to use MessageBoxEx because its need one parameter to be passed (for learning purpose).
I know I've asked similar question, but it is more related to vb.net while this is not.
My assembly is a little rusty, but I was under the impression that all arguments went onto the stack (in reverse order) - I'd have thought you want to be pushing r8 and rdx in as well as the other arguments. Frankly though you might as well just keep doing lea rax, param and push rax for each of the arguments that are pointers.
The order in which the arguments are passed and whether they are passed in registers or on the stack (along with whether caller or callee is responsible for cleanup) is defined by the 'Calling Convention'.
What you are probably thinking of is STDCALL or CDECL, both are calling conventions used in 32-bit Windows that pass arguments on the stack in reverse order (right to left). x64 has moved to a FastCall calling convention where the arguments are passed in forward order (from left to right) and the first 4 arguments are passed in the registers RCX, RDX, R8 & R9. Any arguments beyond 4 are passed on the stack in the same left-to-right order. The original poster had the correct calling convention setup for x64 assembly with MASM. Also, the above responder who said the shadowspace valued subtracted from RSP should be 20h (32d) is correct. The shadow space is allowing space on the stack for the 4 arguments that are passed in by the registers in FastCall.
Changing the code above to:
extrn ExitProcess: PROC extrn MessageBoxExA: PROC .data caption db '64-bit hello!', 0 message db 'Hello World!', 0 .code Start PROC sub rsp, 20h mov rcx, 0 ; hWnd = HWND_DESKTOP lea rdx, message ; LPCSTR lpText lea r8, caption ; LPCSTR lpCaption mov r9d, 0 ; uType = MB_OK push 0 ; wLanguageId call MessageBoxExA mov ecx, eax add rsp, 20h call ExitProcess Start ENDP End
Works just fine in Visual Studio on a 64-bit machine