In x64 assembly, the stack frame, according to Microsoft, should be 16-byte aligned
The stack will always be maintained 16-byte aligned, except within the prolog (for example, after the return address is pushed), and except where indicated in Function Types for a certain class of frame functions.
Assume we have the following function:
void foo() {
long long int foo;
long long int bar;
}
The stack would look something like this:
|-----------|
| rbp |
|-----------|
| foo |
|-----------|
| bar |
|-----------|
| undefined |
|-----------|
So, the stack would need to allocate 20h bytes. And the assembly instruction would look like:
push rbp
mov rbp, rsp
sub 20h ; 32 bytes needed to fulfill alignment requirements
Is my understanding of this correct, or am I way off? I'm also assuming no optimizations.
I have been trying to figure this out myself and I believe I understand what is needed here.
Assuming the CALLER of foo() ensured 16-byte alignment before the call then:
In this scenario I see no need for extra padding, however, you cannot guarantee that the CALLER of your function ensured 16-byte alignment before the call (unless you are working in an environment where it is guaranteed) so you need to make sure by adding the following line of code:
and rsp, -16
so your final code should be:
push rbp
mov rbp, rsp
sub rsp, 10h ; make space for locals foo and bar
and rsp, -16 ; force 16-byte alignment by zeroing last four bits
Now you are sure that the state of the stack is 16-byte aligned before you make any call to a function that may require it.
Note that if you know that the functions you call from your foo() procedure do not need 16-byte alignment then there should be no need to go thru' these hoops.
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