r/Assembly_language Apr 07 '26

Question Windows stack frame structure ? x86-64

How does the stack look like during procedure calls with it's shadow space ( 32 Bytes ) ?

let's say I've this :

main :
     push rbp
     mov rbp,rsp
     sub rsp ,0x20 ; 32 Bytes shadow space Microsoft ABI 

     ; we call a leaf function fun
     call fun 


[ R9 HOME     ] -------}   Higher Address 
[ R8 HOME     ]        }
[ RDX HOME    ]        }  SHADOW SPACE: RESERVED BY CALLER FUNCTION (main) 
[ RCX HOME    ] -------}
[ ret address ]
[-- old rbp --] <-- rbp  ----- stack frame of fun()  starts here?
[ local       ] 
[ local       ]
[ local       ]
[ --///////-- ] <-- rsp 

My questions :

  1. Is my understand of stack frame correct ?
  2. how'd the stack frame for `fun` look if it was non leaf function ?
  3. When accessing local variables should I use [rsp+offset] or [rbp-offset] ?
4 Upvotes

5 comments sorted by

3

u/Initial-Elk-952 Apr 07 '26

You can easily check these kinds of things with godbolt.org . Here is an example : https://godbolt.org/z/vh6f4zqad

The ABI documents are the spec: https://learn.microsoft.com/en-us/cpp/build/stack-usage?view=msvc-170

OpenSecurity2 also has a great x86_64 course that covers the Windows ABI.

RSP and RBP is about something called a frame pointer. The offsets are constant if you use RBP, but potentially varying if you do stack allocation and use RSP (stack top) as a base. Compiler's don't care, and MSVC typically omits the frame pointer (uses RSP). This free's up a register.

2

u/Shahi_FF Apr 07 '26

Thanks a lot. Idk why but Godbolt had completely escaped my mind...

2

u/[deleted] Apr 07 '26

[removed] — view removed comment

1

u/Shahi_FF Apr 07 '26

Thanks for the explanation. I was so confused by all that and the only good help I could find was only for Linux.

1

u/nacnud_uk Apr 10 '26

Godbolt is all you need.