Hello everyone,
I need a little advice. There's not a lot of documentation for x64 programming (in comaprison to 32b). Can anyone explain me stack alignment? To be more clear, I have following code:
[BITS 64]
%include 'win32n.inc'
extern MessageBoxA
extern ExitProcess
section .data
headline db "Greetings",0
my_text db "How are you?",0
section .code
start:
sub rsp,40 ; shadow space, aligns stack
mov rcx,0 ; hWnd = HWND_DESKTOP
mov rdx,my_text ; LPCSTR lpText
mov r8,headline ; LPCSTR lpCaption
mov r9,MB_OK | MB_ICONINFORMATION ; uType = MB_OK
call MessageBoxA ; call MessageBox API function
mov rcx,0 ; uExitCode = MessageBox(...)
call [ExitProcess]
As I read somewhere
In addition to registers, each function has a frame on the run-time stack. This stack grows downwards from high addresses. (...) The end of the input argument area shall be aligned on a 16 (...) byte boundary. In other words, the value (%rsp + 8 ) is always a multiple of 16 when control is transferred to the function entry point. The stack pointer, %rsp, always points to the end of the latest allocated stack frame.
What's not clear to me is why it works with sub rsp,40 while it doesn't work with any other number. As stated above, it should be aligned on a 16 byte boundary. That means 16, 32, 48 etc. Why sub rsp,32 does not work? Why rsp,48 does not work and why does 40 work? I'm little bit confused.
What's even more strange to me is that on a different PC (I use Broadwell while the other PC has Haswell inside), it works with numbers 8, 24, 40 etc. That means 16 byte alignment +8 (like constant). After I call the first function, the stack is in the middle of 16 byte boundary, that's why the constant +8. BUT how should I know that the stack is going to be there? There are so many "why" for me.
Can someone help me and explain me this? Thank you!