2010-07-14 87 views
2

avr-gcc程序中的main()函數將寄存器狀態保存在堆棧中,但是當運行時調用它時,我明白在單片機上沒有任何可返回的東西。這是浪費RAM嗎?如何防止這種狀態儲蓄?爲什麼在調用main()時,avr-gcc會不自覺地保存寄存器狀態?

+1

這可能是特定於您的avr-gcc版本。我無法用4.5.1來觀察這一點。唯一的浪費是'main()'實際上被調用,因此返回地址將無用地躺在棧上,通常情況下main()不返回。 – ndim 2011-04-14 00:09:41

回答

3

最有可能的主要是編寫在同一個標​​準函數。在C中,它非常需要,因爲你可以從某個地方調用它。

請注意,在C++中,遞歸調用main是非法的,因此C++編譯器可能會更好地優化它。但在C中,因爲你的問題指出,遞歸調用main是合法的(如果一個壞主意),所以它需要以與其他函數相同的方式進行編譯。

4

這都是關於C標準的。

什麼都不能阻止你在某個時候退出主界面。你可能不會在你的程序中做到這一點,但其他人可能會這樣做。

此外,您可以通過atexit運行時功能註冊清理處理程序。這些函數需要一個定義好的寄存器狀態才能正確執行,唯一的方法就是保存和恢復主寄存器。

它甚至可能是有用的這樣做: 我不知道AVR,但其他微控制器可以進入低功耗狀態,當他們完成他們的工作,並等待重置。從清除處理程序執行此操作可能是一個好主意,因爲如果您以正常方式退出主程序(就我而言),如果程序通過終止信號被中斷,則會調用此處理程序。

6

編譯器如何確定你不會遞歸調用main()?

1

如何防止這種狀態的保存?

你唯一能做的就是寫你自己的C-Startup例程。這意味着與彙編程序混淆,但您可以跳至main()而不是僅調用它。

1

在我用avr-gcc 4.3.5進行的測試中,如果不是優化太多,它只會保存寄存器。正常級別(-Os或-O2)會導致推送指令被優化。 可以在函數聲明中進一步指定它不會以__attribute__((noreturn))返回。使用-fwhole程序進行全面的程序優化也很有用。

avr-libc中的初始代碼確實使用call來跳轉到main,因爲它指定主可能會返回,然後跳轉到退出(它被聲明爲noreturn並因此不生成任何調用)。如果你覺得太多,你可以鏈接你自己的變體。退出()只是簡單地禁用中斷並進入一個無限循環,有效地停止你的程序,但不會節省任何電力。如果main()永遠不會返回或調用exit(),那麼這是四條指令和兩個字節的堆棧內存開銷。

相關問題