how is the value of 28h
(decimal 40) that is subtracted from rsp
calculated in the following:
option casemap:none
includelib kernel32.lib
includelib user32.lib
externdef MessageBoxA : near
externdef ExitProcess : near
.data
text db 'Hello world!', 0
caption db 'Hello x86-64', 0
.code
main proc
sub rsp, 28h ; space for 4 arguments + 16byte aligned stack
xor r9d, r9d ; 4. argument: r9d = uType = 0
lea r8, [caption] ; 3. argument: r8 = caption
lea rdx, [text] ; 2. argument: edx = window text
xor rcx, rcx ; 1. argument: rcx = hWnd = NULL
call MessageBoxA
xor ecx, ecx ; ecx = exit code
call ExitProcess
main endp
end
from: http://www.japheth.de/JWasm/Win64_1.html
By my understanding I would have to only subtract 20h
since each value I'm using takes 8 bytes into 4 is 20h
. so why is 28h
being subtracted and how does that result in 16 byte alignment?
see also Is reserving stack space necessary for functions less than four arguments?
I believe it's because before main
is called, the stack is aligned. Then after the call
, the act of the call
was to push an 8-byte pointer (the address within the caller to return to, which is the address right after the call instruction) onto the stack. So at the beginning of main
, it's 8 bytes off of the 16-byte alignment. Therefore, instead of 20h
you need 28h
, bringing the actual total to 28h + 8h
(from the call
) or 30h
. Alignment. :)
I had stumbled upon the same case. Tried lurker answer and was fine. Later added some code(by the way, i'm using my own compiler) and got problems.
The problem was that the shadow space address was ending with 8 on the stack. When the shadow space address was ending with 0 ("Stack aligned on 16 bytes"), the call was OK. Adding 8 bytes will crash the app in my last case.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With