为什么在 64 位架构上对齐是 16 字节?

发布于 2024-10-30 09:51:30 字数 850 浏览 1 评论 0原文

(gdb) disas foo
Dump of assembler code for function foo:
0x00000000004004a8 <foo+0>: push   %rbp
0x00000000004004a9 <foo+1>: mov    %rsp,%rbp
0x00000000004004ac <foo+4>: mov    0x13c(%rip),%eax        # 0x4005ee <__dso_handle+30>
0x00000000004004b2 <foo+10>:    mov    %eax,-0x10(%rbp)
0x00000000004004b5 <foo+13>:    lea    -0x10(%rbp),%rax
0x00000000004004b9 <foo+17>:    add    $0x18,%rax
0x00000000004004bd <foo+21>:    mov    %rax,%rdx
0x00000000004004c0 <foo+24>:    mov    $0x400498,%eax
0x00000000004004c5 <foo+29>:    mov    %eax,(%rdx)
0x00000000004004c7 <foo+31>:    leaveq 
0x00000000004004c8 <foo+32>:    retq   
(gdb) l foo
8   void foo() {
9       char overme[4] = "WOW";
10      *(int*)(overme+24) = (int)bad;
11  }

为什么不只是 8 个字节?

(gdb) disas foo
Dump of assembler code for function foo:
0x00000000004004a8 <foo+0>: push   %rbp
0x00000000004004a9 <foo+1>: mov    %rsp,%rbp
0x00000000004004ac <foo+4>: mov    0x13c(%rip),%eax        # 0x4005ee <__dso_handle+30>
0x00000000004004b2 <foo+10>:    mov    %eax,-0x10(%rbp)
0x00000000004004b5 <foo+13>:    lea    -0x10(%rbp),%rax
0x00000000004004b9 <foo+17>:    add    $0x18,%rax
0x00000000004004bd <foo+21>:    mov    %rax,%rdx
0x00000000004004c0 <foo+24>:    mov    $0x400498,%eax
0x00000000004004c5 <foo+29>:    mov    %eax,(%rdx)
0x00000000004004c7 <foo+31>:    leaveq 
0x00000000004004c8 <foo+32>:    retq   
(gdb) l foo
8   void foo() {
9       char overme[4] = "WOW";
10      *(int*)(overme+24) = (int)bad;
11  }

Why not just 8 bytes?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

香草可樂 2024-11-06 09:51:30

gcc 没有将此空间“分配”给变量。相反,x86_64 abi 要求堆栈指针在函数调用时始终保持 16 字节对齐,以防被调用者使用向量化 SSE 数学。这是一个非常愚蠢和浪费的要求(被调用者应该在需要时确保对齐),但这就是标准,并且 gcc 遵循该标准。您可以使用 -mpreferred-stack-boundary=3 来修复它(8 字节对齐,64 位的最小值)。

gcc is not "assigning" this space to the variable. Rather, the x86_64 abi requires the stack pointer to always be 16-byte-aligned at function calls, in case the callee uses vectorized SSE math. It's a really stupid and wasteful requirement (the callee should ensure the alignment if it needs it), but that's the standard, and gcc follows the standard. You can fix it with -mpreferred-stack-boundary=3 (8 byte alignment, the minimum for 64-bit).

长安忆 2024-11-06 09:51:30

它是 8 个字节,而不是 16 个字节。LEA 指令不显示任何与对齐相关的内容,-0x10 只是应用于 RBP 寄存器值的偏移量。可能是为了生成一个小型本地数组的地址。如果代码生成器使用任何 SIMD 指令,则 16 可能是相关的。在两行问题中,这些都看不到。

It is 8 bytes, not 16. The LEA instruction doesn't show anything alignment related, -0x10 is just an offset applied to the value of the RBP register. Probably to generate the address of a small local array. If the code generator uses any SIMD instructions then 16 could be relevant. None of which is visible in a two-liner question.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文