2015-11-04 99 views
0

当分析由g ++ 5.2.0生成的二进制代码时,我发现编译器经常分配似乎没有被任何程序元素使用的内存。下面是一个例子。g ++在堆栈上分配未使用的内存是什么?

的源代码是

void 
cxx_pretty_printer::declarator (tree t) 
{ 
    this->direct_declarator (t); // A virtual function call 
} 

和生成的二进制

0x8427ce8 _ZN18cxx_pretty_printer10declaratorEP9tree_node: 
0x8427ce8 push %ebp 
0x8427ce9 mov  %esp, %ebp 
0x8427ceb sub  $0x8, %esp 
0x8427cee mov  0x8(%ebp), %eax 
0x8427cf1 mov  0x0(%eax), %eax 
0x8427cf3 add  $0x4c, %eax 
0x8427cf6 mov  0x0(%eax), %eax 
0x8427cf8 sub  $0x8, %esp 
0x8427cfb pushl 0xc(%ebp) 
0x8427cfe pushl 0x8(%ebp) 
0x8427d01 call *0x0(%eax,0) 
0x8427d03 add  $0x10, %esp 
0x8427d06 nop 
0x8427d07 leave 
0x8427d08 ret 

我不明白为什么在0x8427ceb和0x8427cf8代码应该存在。编译器减少了堆栈寄存器,这似乎是它在堆栈上分配了一些空间。然而,这个空间从来没有被任何东西占用。

有什么特别的原因可以让g ++做到这一点吗?我使用的选项

-O2 -fno-exceptions -fno-rtti -fasynchronous-unwind-tables 
+0

您使用了哪些优化标志?你可以使用'g ++ -Wall -O3 -fverbose-asm -S'进行编译,然后查看生成的'.s'汇编文件(甚至可以通过'-fdump-tree-all'来理解,通过数百个转储的文件,正在*编译器内部发生)。 –

+2

'有什么特别的理由让g ++做到这一点?':上帝我们相信。编译器会确保您可以/不必知道的“优化”。 – 101010

+3

您启用了哪些优化?此外,其中一些可能是由于函数调用的堆栈对齐要求。 – EOF

回答

-1

由于EOF在评论中提到,这是由于栈对齐,并须通过设置选项-mpreferred-stack-boundary改变。信用去解答https://stackoverflow.com/a/1061942/696110

提到的选项也会影响C编译。

+0

显示证明C具有相同的对齐要求。 – Olaf

+0

@Olaf你如何在我引用的答案中提出要求?顺便说一下,这个问题有一个C标签,你可能想删除它。 – uraj

+0

你认为有可能破解ABI有助于解决你的问题吗?那么,我希望我永远不必调试你的代码,或者你在安全关键领域工作。 – Olaf