void function(int a, int b, int c) {
char buffer1[5];
char buffer2[10];
}
并生成相应的汇编代码输出
pushl %ebp
movl %esp,%ebp
subl $20,%esp
作者解释说,由于计算机按字大小的倍数寻址内存,编译器在堆栈上保留了20个字节(8个字节用于缓冲区1,12个字节用于缓冲区2)。
我尝试重现此示例并获得以下结果:
pushl %ebp
movl %esp, %ebp
subl $16, %esp
有不同的结果!我尝试了各种buffer1和buffer2大小的组合,现代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
char
值进行对齐有意义吗? - Matti Virkkunen