執行程序時我們需要 c 庫嗎?
執行檔應該是機器碼。
因此,無需 c 庫即可進行系統呼叫。
但是,我無法弄清楚這張圖片是什麼意思?
它只是一種抽象方法嗎?
您有一個呼叫庫函式的程序。在這種情況下,它是系統標準庫,也稱為“C 庫”(但還有許多其他庫可以從 C 程式碼中呼叫,這只是一個名稱)。“庫函式”是指函式的程式碼作為庫的一部分分發。程序在執行時可以通過兩種方式呼叫庫函式。
如果庫是靜態連結到程序中的,這意味著當程序建構時,結果是一個執行檔,其中包括編譯程序原始碼的結果(
main
函式和程序中的任何其他函式),以及函式來自庫,例如printf
(連結器在一個名為的文件/lib/libc.a
或某個類似位置¹中找到它)。這意味著在建構程序時完全執行“連結器”步驟。所有“(Lib ref)”位都被庫中的程式碼替換。當程序執行時,它不需要任何庫文件。的程式碼printf
在程序執行檔中。由於write
是系統呼叫而不是庫函式²,因此其程式碼位於核心內部。如果庫是動態連結的,則圖片中的連結器步驟不包括執行檔中的庫程式碼。它所做的只是在程序啟動時填寫一些指令以從庫中載入某些函式:執行檔仍然包含“(Lib ref)”位。當執行檔被執行時,它做的第一件事就是載入共享庫文件(
/lib/libc.so
或一些類似的文件)並將程序所需的函式名與庫提供的函式名匹配。術語“抽象方法”相當模糊。不要執著於它。您可以說動態連結抽象了庫,因為相同的執行檔可以與庫的不同實現一起執行。
該圖似乎在解釋靜態連結。在現實生活中,動態連結在多道程序系統中最為常見。靜態連結有兩個主要缺點:如果不升級所有使用它的程序就無法升級庫(例如修復錯誤),如果許多程序使用同一個庫,那麼您必須儲存盡可能多的程式碼副本。靜態連結對於只執行單個程序並且只能通過替換整個程式碼映像進行升級的低端嵌入式系統來說很好,但是動態連結對於執行許多不同程序的系統來說是常態。
¹文件名可能比您系統上的文件名更複雜,但這與此答案無關。
²實際上,有一個庫函式叫做
write
,但它所做的只是進行系統呼叫。在我的回答中,我指的是該名稱的系統呼叫。