2015-11-04 82 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