简体   繁体   中英

Understanding 16-byte padding and function prolog in x64 assembly

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:

  • The CALL statement (by the caller of your function foo() ) puts 8-bytes on the stack ie the return address. [Stack not 16 Byte Aligned]
  • Then your function pushed RBP on the stack (8-bytes). [Stack is 16 Byte Aligned]
  • You make space for the FOO & BAR local variables adding 2x 8-bytes. [Stack is still 16-Byte Aligned]

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM