I found the sample program below somewhere on the Web. Various copies of it abound, usually with small differences. But my question concerns the size of the shadow area at the top of the stack when calling a function from the Windows API. This program works perfectly as shown, with decimal 40 subtracted from the stack pointer, to allow room for the 4 parameters that are passed in registers, plus one more. However, in this case there is no 5th parameter, and yet if the sub rsp, 40
is changed to sub rsp, 32
, and no other changes are made, the 'Hello world' window is no longer displayed! Is there some reason why when only 4 parameters are involved, all of which are passed in registers, it's still necessary to reserve 40 (5*8) bytes at the top of the stack rather than only 32 (4*8)?
; Sample x64 Assembly Program
; Chris Lomont 2009 www.lomont.org
; command to assemble is:
; ml64 hello.asm /link /subsystem:windows /defaultlib:kernel32.lib /defaultlib:user32.lib /entry:Start
extrn ExitProcess: PROC ; in kernel32.lib
extrn MessageBoxA: PROC ; in user32.lib
.data
caption db '64-bit hello!', 0
message db 'Hello World!', 0
.code
Start PROC
sub rsp, 40 ; shadow space, aligns stack
mov rcx, 0 ; hWnd = HWND_DESKTOP
lea rdx, message ; LPCSTR lpText
lea r8, caption ; LPCSTR lpCaption
mov r9d, 0 ; uType = MB_OK
call MessageBoxA ; call MessageBox API function
mov ecx, eax ; uExitCode = MessageBox(...)
call ExitProcess
Start ENDP
End