2017-07-18 49 views
4

我很抱歉,如果這聽起來應該是微不足道的,但是我不能找出一種直觀的方式來Google它,爲什麼有些內核動作像保存寄存器的當前狀態和堆棧(只是提及幾個)在大會寫?爲什麼他們不能用C編寫,因爲畢竟,編譯完成後,我們所得到的只是目標代碼?除了使用ollydbg時,您注意到在函數調用之前(在C中),寄存器的當前狀態被推入堆棧爲什麼有些內核動作無法寫入C

+5

因爲沒有辦法在C中表達這個?這很簡單...(C是硬件的抽象) –

+5

C是一種高級語言,與硬件無關。爲了操縱寄存器,你必須設計一個帶有寄存器的體系結構,這不是以語言c編程的先決條件。 – Ctx

+0

「你注意到一個函數調用(C語言)之前,寄存器的當前狀態推到棧」的一些通用寄存器可根據需要推,但這不是整個交易在大多數架構。例如:如果需要將進程上下文換出,那麼內存管理硬件寄存器也需要被換出。 –

回答

0

「從異常返回」沒有C等效項。 C編譯器無法翻譯程序集可以執行的所有操作。例如,如果你編寫一個操作系統,你需要在中斷服務程序中有一個特殊的返回函數,該函數返回到中斷啓動的地方,而C編譯器不能轉換這樣的功能,它只能用匯編表示。

又見Is assembly strictly required to make the "lowest" part of an operating system?

+3

一些C編譯器具有專有擴展支持類似功能的深入瞭解「異常返回。」 – fuz

+0

@fuz yes和no。其中一個例子是gcc + arm CMSIS - 即使他編寫了RTOS,編碼人員也不必觸碰彙編程序。但這只是因爲許多函數已經被ARM作爲內聯彙編編寫。例如'__attribute __((always_inline))__STATIC_INLINE空隙__set_BASEPRI(uint32_t的值) { __asm易失性( 「MSR BASEPRI,%0」: 「R」(值): 「存儲器」); }'。但即使你可以用C編寫它,你仍然需要深入瞭解底層硬件 –

0

Context switching是至關重要的,必須是不應該在高級語言編寫真的快。

+4

這不是真正的原因。現代編譯器可以生成與手寫彙編一樣快的代碼。 – fuz

+2

@fuz和一些時間,比_handwritten_ assembly更好。 –

+1

並非所有的說明@fuz。 「和手寫彙編一樣快」有時候這只是一個謊言。順便說一句,這只是因爲歷史。 – sdao

2

C不能保證它修改了需要修改的寄存器。

C只是實現了您在代碼中編寫的邏輯,並且語言給出的解釋將如您期望的那樣完全隱藏解釋背後的細節。

如果你想要一種像set the X register with a given valuemove data from register X to register Y這樣的邏輯,因爲它有時需要在內核中完成,所以這種邏輯不是由C語言定義的。

4

在編寫OS的主要目標是保持最高抽象,使不同架構的代碼重用,但最終難免有架構

每臺機器都以非專業化的方式執行非常低級別的功能,因此沒有一般的編程語言能夠承受。

使用高級語言(考慮指令序列,涉及的寄存器以及最終關鍵的CPU時序和優先級),無法有效地對任務切換,總線控制,器件中斷處理等進行有效編碼。

另一方面,使用混合編程,即內聯彙編程序甚至都不方便,因爲精心製作的模塊不會更抽象,包含不能重用的特定體系結構代碼。

通用的解決方案是編寫遵循最高抽象級別的所有代碼,將專用代碼減少到幾個模塊。這些程序完全用匯編編寫,通常在提供的輸入和期望的輸出方面很好地定義,所以程序員可以在不同的體系結構上產生相同的結果。

然後通過簡單地切換一組裝配例程完成針對不同CPU的編譯。

1

C是一種通用的高級語言,並非特定於一個目標。但是在內核層面上,你需要做的事情是C語言根本無法做到的具體目標。啓用中斷或配置MMU或配置與保護機制相關的內容。在某些目標上,這些項目和其他項目使用地址空間中的寄存器進行配置,但在某些目標上需要特定的彙編語言指令,因此C不能使用,因此必須進行彙編。如果不是很多,通常至少有一件事你必須爲每個目標使用匯編。

有時它是希望正確指令的簡單情況下使用,例如一個32位的商店必須用於某些操作,以確保不希望編譯器得到它的權利,然後使用ASM。

相關問題