为什么堆栈帧按 24 字节对齐?
Why stack frame aligned by 24 bytes?
我正在阅读 Randal E. Bryant 和 David R. O'Hallaron 的 Computer Systems: A Programmer's Perspective 第 3 版。
在第3章和7.5节中,有图演示了堆栈帧是如何分配的,如下所示:
我不明白为什么需要第 4 行和第 12 行。似乎不需要这些行,因为根本没有使用多余的 8 字节堆栈内存。
如评论所示,恕我直言,似乎不可避免地分配了 24 个字节对齐堆栈帧:
- 分别为
pushq %rbp
和 pushq %rbx
添加 16 个字节
- ,以及
subq , %rsp
的 8 个字节
所以,我的问题可以概括为“为什么堆栈帧按 24 字节对齐?”
24 字节不是 2 的幂,因此不能对齐。真正的对齐是 16 个字节,你忘了考虑 call
指令也将 8 个字节压入堆栈。因此,堆栈指针总共移动了 32 个字节,保持对齐到 16 个字节。
这与 x64 ABI(Microsoft 和 SystemV)一致。在调用函数之前,堆栈必须在 16 字节边界上对齐(在您的示例中为“调用 Q”)。假设堆栈最初位于 16 字节边界处。当程序到达“P”标签时(由于“call P”指令),RSP 指向下面的 8 个字节,因为“call”将 RSP 减 8 并将 RIP(8 个字节)保存在 *RSP 处。然后,有两个“pushq”(第 2 行和第 3 行),每个都将 RSP 减少 8,因此 RSP 仍然未对齐。这就是为什么编译器必须在第 8 行和第 10 行执行“call Q”之前减去 8 以对齐 RSP。
这篇文章很好地描述了 x86/x64 ABI:
https://en.wikipedia.org/wiki/X86_calling_conventions
我正在阅读 Randal E. Bryant 和 David R. O'Hallaron 的 Computer Systems: A Programmer's Perspective 第 3 版。
在第3章和7.5节中,有图演示了堆栈帧是如何分配的,如下所示:
我不明白为什么需要第 4 行和第 12 行。似乎不需要这些行,因为根本没有使用多余的 8 字节堆栈内存。
如评论所示,恕我直言,似乎不可避免地分配了 24 个字节对齐堆栈帧:
- 分别为
pushq %rbp
和pushq %rbx
添加 16 个字节 - ,以及
subq , %rsp
的 8 个字节
所以,我的问题可以概括为“为什么堆栈帧按 24 字节对齐?”
24 字节不是 2 的幂,因此不能对齐。真正的对齐是 16 个字节,你忘了考虑 call
指令也将 8 个字节压入堆栈。因此,堆栈指针总共移动了 32 个字节,保持对齐到 16 个字节。
这与 x64 ABI(Microsoft 和 SystemV)一致。在调用函数之前,堆栈必须在 16 字节边界上对齐(在您的示例中为“调用 Q”)。假设堆栈最初位于 16 字节边界处。当程序到达“P”标签时(由于“call P”指令),RSP 指向下面的 8 个字节,因为“call”将 RSP 减 8 并将 RIP(8 个字节)保存在 *RSP 处。然后,有两个“pushq”(第 2 行和第 3 行),每个都将 RSP 减少 8,因此 RSP 仍然未对齐。这就是为什么编译器必须在第 8 行和第 10 行执行“call Q”之前减去 8 以对齐 RSP。
这篇文章很好地描述了 x86/x64 ABI: https://en.wikipedia.org/wiki/X86_calling_conventions