简体   繁体   English

gcc堆栈优化

[英]gcc stack optimization

Hi I have a question on possible stack optimization by gcc (or g++).. 嗨,我有一个关于gcc(或g ++)可能的堆栈优化的问题..

Sample code under FreeBSD (does UNIX variance matter here?): FreeBSD下的示例代码(这里的UNIX差异是否重要?):

void main() {
   char bing[100];
   ..
   string buffer = ....;
   ..
}

What I found in gdb for a coredump of this program is that the address of bing is actually lower than that buffer (namely, &bing[0] < &buffer). 我在gdb中找到的这个程序的coredump是bing的地址实际上低于那个缓冲区(即&bing [0] <&buffer)。

I think this is totally the contrary of was told in textbook. 我认为这完全与教科书中的相反。 Could there be some compiler optimization that re-organize the stack layout in such a way? 是否有一些编译器优化以这种方式重新组织堆栈布局?

This seems to be only possible explanation but I'm not sure.. 这似乎只是可能的解释,但我不确定..

In case you're interested, the coredump is due to the buffer overflow by bing to buffer (but that also confirms &bing[0] < &buffer). 如果你感兴趣的话,coredump是由于bing缓冲区溢出缓冲区(但这也确认了&bing [0] <&buffer)。

Thanks! 谢谢!

Compilers are free to organise stack frames (assuming they even use stacks) any way they wish. 编译器可以按照自己的意愿自由组织堆栈帧(假设它们甚至使用堆栈)。

They may do it for alignment reasons, or for performance reasons, or for no reason at all. 他们可能出于协调原因,出于性能原因,或者根本没有任何理由这样做。 You would be unwise to assume any specific order. 假设任何特定的订单你是不明智的。

If you hadn't invoked undefined behavior by overflowing the buffer, you probably never would have known, and that's the way it should be. 如果你没有通过溢出缓冲区来调用未定义的行为,那么你可能永远都不会知道,这应该是它应该的样子。

A compiler can not only re-organise your variables, it can optimise them out of existence if it can establish they're not used. 编译器不仅可以重新组织您的变量,如果它们可以确定它们未被使用,它可以优化它们。 With the code: 随着代码:

#include <stdio.h>
int main (void) {
   char bing[71];
   int x = 7;
   bing[0] = 11;
   return 0;
}

Compare the normal assembler output: 比较正常的汇编程序输出:

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

with the insanely optimised: 疯狂优化:

main:
    pushl   %ebp
    xorl    %eax, %eax
    movl    %esp, %ebp
    popl    %ebp
    ret

Notice anything missing from the latter? 注意后者缺少什么? Yes, there are no stack manipulations to create space for either bing or x . 是的, 没有堆栈操作来为bingx创建空间。 They don't exist. 它们不存在。 In fact, the entire code sequence boils down to: 实际上,整个代码序列归结为:

  • set return code to 0. 将返回码设置为0。
  • return. 返回。

A compiler is free to layout local variables on the stack (or keep them in register or do something else with them) however it sees fit: the C and C++ language standards don't say anything about these implementation details, and neither does POSIX or UNIX. 编译器可以自由地在堆栈上布局局部变量(或者将它们保存在寄存器中或对它们执行其他操作)但是它认为合适:C和C ++语言标准没有说明这些实现细节,POSIX或UNIX。 I doubt that your textbook told you otherwise, and if it did, I would look for a new textbook. 我怀疑你的教科书告诉过你,如果确实如此,我会寻找一本新的教科书。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM