gpt4 book ai didi

c - 今天和 20 年前的内存对齐

转载 作者:太空狗 更新时间:2023-10-29 16:38:45 24 4
gpt4 key购买 nike

在著名的论文“Smashing the Stack for Fun and Profit”中,它的作者取了一个C函数

void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
}

并生成相应的汇编代码输出

pushl %ebp
movl %esp,%ebp
subl $20,%esp

作者解释说,由于计算机以字长的倍数寻址内存,因此编译器在堆栈上保留了 20 个字节(8 个字节用于 buffer1,12 个字节用于 buffer2)。

我尝试重新创建这个示例并得到以下内容

pushl   %ebp
movl %esp, %ebp
subl $16, %esp

不一样的结果!我尝试了缓冲区 1 和缓冲区 2 的各种大小组合,现代 gcc 似乎不再将缓冲区大小填充为字大小的倍数。相反,它遵守 -mpreferred-stack-boundary 选项。

举个例子——使用论文的算术规则,对于 buffer1[5] 和 buffer2[13],我会在堆栈上保留 8+16 = 24 个字节。但实际上我得到了 32 个字节。

这篇论文很旧,从那以后发生了很多事情。我想知道,究竟是什么促使了这种行为的改变?是转向 64 位机器吗?还是别的?

编辑

代码是在 x86_64 机器上使用 gcc 版本 4.8.2 (Ubuntu 4.8.2-19ubuntu1) 编译的,如下所示:

$ gcc -S -o example1.s example1.c -fno-stack-protector -m32

最佳答案

改变的是SSE ,这需要 16 字节对齐,这在旧的 gcc 文档中涵盖 -mpreferred-stack-boundary=num上面写着(强调我的):

On Pentium and PentiumPro, double and long double values should be aligned to an 8 byte boundary (see -malign-double) or suffer significant run time performance penalties. On Pentium III, the Streaming SIMD Extension (SSE) data type __m128 suffers similar penalties if it is not 16 byte aligned.

这也得到了论文 Smashing The Modern Stack For Fun And Profit 的支持。其中涵盖了其他现代变化,这些变化打破了为了乐趣和利润而粉碎堆栈

关于c - 今天和 20 年前的内存对齐,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30222214/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com