CSAPP中的汇编代码

CSAPP中的汇编代码,c,assembly,x86-64,att,C,Assembly,X86 64,Att,在《CSAPP 3.7.5寄存器中的本地存储》一书中,有一个调用函数: long P(long x, long y) { long u = Q(y); long v = Q(x); return u + v; } 调用函数生成的汇编代码为: P: pushq %rbp pushq %rbx subq $8, %rsp Align stack frame movq %rdi, %rbp movq %

在《CSAPP 3.7.5寄存器中的本地存储》一书中,有一个调用函数:

long P(long x, long y)
{
     long u = Q(y);
     long v = Q(x);
     return u + v;
}
调用函数生成的汇编代码为:

P:
  pushq    %rbp
  pushq    %rbx
  subq     $8, %rsp       Align stack frame
  movq     %rdi, %rbp
  movq     %rsi, %rdi
  call     Q
  movq     %rax, %rbx
  movq     %rbp, %rdi
  call     Q
  addq     %rbx, %rax
  addq     $8, %rsp
  popq     %rbx
  popq     %rbp
  ret

我无法理解第3行
subq$8,%rsp
。书上说它是用来对齐堆栈框架的。为什么在这里使用机器对齐堆栈帧?

64位System V ABI在调用函数之前需要16字节对齐。调用指令之后,您在函数中,但返回地址已推送到堆栈上。堆栈现在未对齐8字节(返回地址为8字节)。按RBP再减去8个字节,以便堆栈再次对齐。按下RBX会使其再次偏离8。
subq$8,%rsp
恰好减去另一个8,再次重新调整堆栈。现在,当您执行
call Q
时,堆栈将在16字节边界上对齐(堆栈指针将被16)SIMD指令,该指令可以对内存中的多个字执行并行操作,要求这些字是从16字节倍数的地址开始的块。对此有很好的解释