2014-08-23 65 views
19

是否可以在C中完全編寫操作系統?是否可以在C中完全編寫一個操作系統?

通過完全,我包括一切都交給了引導程序,而不是BIOS/UEFI。

+1

這取決於你說「操作系統」時的實際含義。我讀過一本關於ARM的書,可能有一些Cortex-M處理器(非常有限,用於MCU),但很可能在許多其他核心上,您將被迫至少使用一些基本的程序集組態。 – user35443 2014-08-23 09:10:35

回答

20

問題的傳統答案是「你能寫一個完全在C中的程序」是「否」。原因是C程序沒有辦法建立自己的堆棧。

幾乎每一個處理器有需要指向至少一個寄存器,它指向在堆棧(通常稱爲幀指針)的當前地址和有時有一個第二寄存器(通常稱爲堆棧指針)堆棧中下一個未使用的地址。沒有辦法在語言本身中使用任何表達式或語句來將堆棧指針或幀指針設置爲絕對值。 (過程調用和返回可以添加和從堆棧指針減,但有沒有辦法把它初始化爲已知值。)

POSIX定義了一組函數,setcontextgetcontextmakecontextswapcontext(幾乎總是寫在至少部分是彙編器),這將使您能夠讀寫堆棧和幀指針。

不幸的是,setcontext家庭的功能沒有得到廣泛實施。

7

理論上是的,但不是一切。

引導加載程序和實模式的東西,你可以找到一些舊的16位編譯器(例如,渦輪增壓C),告訴他要輸出純二進制,並把它寫所有的東西。
,或者在GCC你可以把asm(".code16gcc")在你的代碼的頂部,但我不建議這一點,因爲GCC是不能夠直接輸出16位代碼,結果彙編程序可能需要超過512個字節。

對於其他的東西,抵消大會的使用是不可能的。
是的,您可以隱藏內聯函數(IN \ OUT,CRx寄存器和內容)中的所有組裝線,但對於其他內容(如中斷),您將被迫使用組裝。

編輯
現在GCC(4.9.0)支持-m16選項使16位代碼生成,因此該組件使用可以對之類的東西啓動扇區/引導加載器可以進一步減小(一些比特仍然需要它雖然)。

7

這取決於你用C

意思

如果你的意思是由ISO定義的,只在定義行爲依託,而你認爲​​在硬件上運行一個常見的各種操作系統的標準C語言編程,那麼不,在C中編寫實用的操作系統是不可能的,因爲C缺乏很多設施,特別是訪問硬件和操縱單獨的程序。

是可能的寫操作的系統,由C程序並且僅至C設施提供輸入/輸出,但不是實際的硬件上運行的OS。您可以通過這種方式爲機器及其操作系統編寫仿真器。

如果你允許實現特定的行爲,那麼答案是平凡的,因爲實現允許添加他們認爲合適的擴展。這絕對有可能有一個C實現,其中operating_system();是實現操作系統的程序的源代碼。

如果您的意思是是否可以使用典型的C編譯器在不使用任何程序集的情況下構建操作系統(包括運行時環境),那麼答案通常是否定的,因爲C編譯器通常缺少一些僅爲對操作系統編寫者的興趣,比如執行上下文切換和建立堆棧所需要的東西。然而,這不是絕對的規則。如果您喜歡,它取決於運行時環境的哪些部分來自編譯器編寫器,哪些部分來自OS編寫器。

+0

在相當數量的平臺上編寫操作系統,而不用編寫單行彙編語言(僅使用編譯器附帶的庫)是可能的,儘管通常最好是編寫至少一點機器碼。例如,在許多平臺上,人們可以定義一個'jmp_buff'和'char []'的聯合體(作爲靜態的),讓程序入口點分別寫入其中的字符,然後不加入「longjmp」使任何堆棧的使用[請注意,memcpy甚至結構分配可能是一個子程序調用,因此不好]。 – supercat 2015-06-30 15:53:30

+0

使用一點點內聯彙編來設置堆棧可能會比逐個創建'jmp_buff'更清潔(並且可能更具可移植性),但是使用諸如'jmp_buff'之類的技術將使它成爲可能,許多實現,建立系統而不需要編譯C代碼以外的任何東西。 – supercat 2015-06-30 15:55:53

相關問題