C++ gcc堆栈优化
嗨,我有一个关于gcc(或g++)可能的堆栈优化的问题 FreeBSD下的示例代码(UNIX差异在这里重要吗?) 我在gdb中找到的这个程序的coredump的地址是 bing的值实际上低于该缓冲区(即&bing[0]<&buffer) 我认为这与教科书上讲的完全相反。可以吗 在这种情况下,可以进行一些编译器优化来重新组织堆栈布局 路 这似乎是唯一可能的解释,但我不确定 如果您感兴趣,coredump是由于 bing到缓冲区(但这也确认了&bing[0]<&buffer)C++ gcc堆栈优化,c++,optimization,gcc,g++,C++,Optimization,Gcc,G++,嗨,我有一个关于gcc(或g++)可能的堆栈优化的问题 FreeBSD下的示例代码(UNIX差异在这里重要吗?) 我在gdb中找到的这个程序的coredump的地址是 bing的值实际上低于该缓冲区(即&bing[0]
谢谢编译器可以自由地在堆栈上布局局部变量(或者保持它们在登记中或者做其他事情),但是它看起来合适:C和C++语言标准没有对这些实现细节说什么,POSIX或UNIX也不讲。我怀疑你的教科书是否告诉你了,如果它告诉了你,我会寻找一本新的教科书。编译器可以随意组织堆栈帧(假设他们甚至使用堆栈) 他们这样做可能是出于一致性原因,也可能是出于性能原因,或者根本没有任何原因。如果你想订任何特定的订单,那是不明智的 如果您没有通过溢出缓冲区来调用未定义的行为,您可能永远也不会知道,这就是应该的方式 编译器不仅可以重新组织您的变量,还可以在确定它们未被使用的情况下对它们进行优化。使用代码:
#include <stdio.h>
int main (void) {
char bing[71];
int x = 7;
bing[0] = 11;
return 0;
}
随着疯狂的优化:
main:
pushl %ebp
xorl %eax, %eax
movl %esp, %ebp
popl %ebp
ret
注意到后者遗漏了什么吗?是的,没有为bing
或x
创建空间的堆栈操作。他们不存在。事实上,整个代码序列归结为:
- 将返回代码设置为0
- 返回
typedef char*字符串代码>在main
某处之前?:-)感谢您的详细输入!我想我一定是从一些关于缓冲区溢出的教科书上读到的,它假设了关于如何编写代码的堆栈布局:)虽然你对标准的看法是正确的,但教科书有一个习惯,一开始会过度简化事情,然后在更高级的课程中纠正细节。例如,你先学习牛顿物理学,然后他们告诉你,它在接近光速时不起作用。编译器文本也会这么做,这并不奇怪。@Karl:“过于简化”和“不正确”是有区别的。牛顿力学是非相对论速度下的一个伟大近似;声称变量的顺序必然会对它们在内存中的排列方式产生任何影响,这不是一种有效的近似或简化。
main:
pushl %ebp
movl %esp, %ebp
andl $-16, %esp
subl $80, %esp
movl %gs:20, %eax
movl %eax, 76(%esp)
xorl %eax, %eax
movl $7, (%esp)
movb $11, 5(%esp)
movl $0, %eax
movl 76(%esp), %edx
xorl %gs:20, %edx
je .L3
call __stack_chk_fail
.L3:
leave
ret
main:
pushl %ebp
xorl %eax, %eax
movl %esp, %ebp
popl %ebp
ret