2015-02-11 32 views

回答

1

如果你做一些驅動程序/內核開發,你可以使用-nostdlib從臃腫的stdlib中刪除你的模塊。然而,爲了在整個硬件上保持一致的行爲,你還要刪除GCC所有的內部攻擊。

http://gcc.gnu.org/onlinedocs/gcc-4.6.1/gcc/Link-Options.html

-nostdlib

不要使用標準系統啓動文件或鏈接時庫。沒有啓動文件,只有您指定的庫將 傳遞給鏈接器,指定鏈接系統 庫(如-static-libgcc或-shared-libgcc)的選項將被忽略。 編譯器可能會生成對memcmp,memset,memcpy和memmove的調用。 這些條目通常由libc中的條目解析。當指定此 選項時,應通過其他一些機制提供這些條目 。

-nostdlib和-nodefaultlibs旁路的標準庫之一是libgcc.a,它是GCC用來克服特定機器缺點的內部子例程庫,或者某些語言​​的特殊需求 。 (有關libgcc.a的更多 討論,請參閱與GCC輸出接口,在大多數情況下,即使您想避開其他標準庫,也需要libgcc.a。換句話說,當您在 中指定-nostdlib或-nodefaultlibs時,通常也應該指定-lgcc 。這可確保您沒有未解決的對內部GCC庫子例程的參考 。 (例如,`__main',用來 確保C++構造將被稱爲;參見collect2)

https://gcc.gnu.org/onlinedocs/gcc-4.6.1/gccint/Interface.html#Interface

3接口至GCC輸出

GCC通常被配置爲使用目標系統上正在使用的相同函數調用約定 。這是通過描述的 機器描述宏完成的(請參閱目標宏)。

但是,在某些目標機器上返回的結構和聯合值的執行方式不同 。因此,返回這種類型的PCC 編譯的函數不能從使用GCC編譯的代碼中調用,反之也不能使用 編譯。這不會經常造成麻煩,因爲很少的Unix庫會返回結構或聯合。

GCC代碼返回長度爲1,2,4或8個字節的結構和聯合,其長度與用於int或雙返回值的相同寄存器相同。 (GCC 通常也會在寄存器中分配這些類型的變量。) 其他大小的結構和聯合通過將其存儲到調用者傳遞的地址(通常在寄存器中)返回給 而返回。目標 掛鉤TARGET_STRUCT_VALUE_RTX告訴GCC在何處傳遞此地址。

與此相反,在大多數目標機器PCC通過將數據複製到靜態存儲的區域返回結構和聯合任何大小的 ,和 然後返回該存儲的地址,好像它是一個指針 值。來電者必須將該存儲區域的數據複製到需要值的地方 。這比GCC使用的方法 慢,並且不能重入。

在一些目標機器上,例如RISC機器和80386, 標準系統慣例是將要返回值的地址 傳遞給子例程。在這些機器上,當使用此方法時,GCC已配置爲 以與標準編譯器兼容。 它可能不兼容1,2,4或8個字節的結構。

GCC使用系統的標準慣例來傳遞參數。在 有些機器上,前幾個參數傳入寄存器;在 其他,所有都在堆棧上傳遞。在任何機器上使用 寄存器傳遞參數是可能的,這可能會導致顯着的加速。但結果將是完整的 與遵循標準約定的代碼不兼容。所以 只有當您切換到GCC作爲系統的唯一 C編譯器時,此更改纔是實用的。一旦我們擁有完整的GNU系統,我們可以在某些機器上實現通過 的註冊參數,以便我們可以用GCC編譯庫。

在某些機器(特別是SPARC)上,某些類型的參數 被「通過不可見參考」傳遞。這意味着值爲 存儲在內存中,並且內存位置的地址被傳遞給 子例程。

如果使用longjmp,請注意自動變量。 ISO C說 沒有聲明爲volatile的自動變量在longjmp後面有未定義的 值。這就是GCC所做的所有承諾,因爲 很難正確恢復寄存器變量,並且GCC的一個特性是可以將變量存入寄存器,而不需要你的要求。

相關問題