.c程序要被轉化爲可執行文件,並以二進制磁盤文件的形式存放起來。編程
過程由GCC編譯器驅動程序完成:數組
GCC讀取hello.c(源程序,文本) -> 通過預處理器(cpp),讀取系統頭文件內容並插入程序 -> hello.i(修改後源程序,文本) -> 通過編譯器(ccl) -> hello.s(彙編程序,文本) -> 彙編器(as),翻譯爲機器語言指令 -> hello.o(可重定位目標程序,二進制) -> 連接器(ld),程序中調用的一些標準C庫函數如printf -> hello(可執行目標程序,二進制)可加載到內存中,由系統執行緩存
1.總線(傳送定長的word)併發
2.I/O設備函數
每一個IO設備都經過一個控制器或適配器與IO總線相連,前者是IO設備自己或者主板上的芯片組;後者是插在主板插槽上的卡操作系統
3.主存線程
臨時存儲設備,在處理器執行程序時,用來 存放程序和程序處理的數據。翻譯
從物理上說,主存是一組DRAM芯片組成的;邏輯上看,存儲器是一個線性的字節數組,每一個字節都有其惟一的地址(數組索引),地址從0開始。設計
4.處理器blog
中央處理器(CPU),解釋(或執行存儲在主存中指令的引擎)。處理器的核心是一個大小爲一個字的存儲設備(或寄存器),成爲程序計數器(PC)。在任什麼時候候,PC都指向主存中的某條機器語言指令(即含有該條指令的地址)。
總之就是由主存中存儲數據,CPU中的寄存器經過總線讀寫主存與外設獲取數據後進行操做,最後再將REG中的數據要麼存主存要麼給IO
上圖是計算機系統的分層視圖。操做系統有兩個基本功能:1.防止硬件被失控的應用程序濫用 2.嚮應用程序提供簡單一致的機制來控制複雜而又一般大不相同的低級硬件設備。操做系統經過幾個基本的抽象概念來實現這兩個功能:進程,虛擬內存和文件
文件:對IO設備的抽象表示
虛擬內存:對主存和磁盤IO設備的抽象表示
進程:對處理器,主存和IO設備的抽象表示
操做系統對一個正在運行的程序的一種抽象。
併發運行:看似同時,實則多進程分時佔用CPU,經過處理器在進程間切換實現。該交錯執行的機制成爲上下文切換。
上下文:操做系統保持跟蹤進程運行所需的全部狀態信息,該狀態稱爲上下文
從一個進程到另外一個進程的轉換是由操做系統內核管理的。內核是操做系統代碼常駐主存的部分。當應用程序須要操做系統的某些操做時會執行系統調用指令,將控制權傳遞給內核,而後內核執行被請求的操做並返回應用程序。
一個進程可由多個稱爲線程的執行單元(顆粒更小)組成,每一個線程都運行在進程的上下文中,並共享一樣的代碼和全局數據。
虛擬內存是一個抽象概念,它爲每一個進程提供了一個假象,即每一個進程都在獨佔地使用主存。每一個進程看到的內存都是一致的,稱爲虛擬地址空間。圖1-13所示的是Linux進程的虛擬地址空間(其餘Unix系統的設計也與此相似)。在Linux中,地址空間最上面的區域是保留給操做系統中的代碼和數據的,這對全部進程來講都是同樣。地址空間的底部區域存放用戶進程定義的代碼和數據。請注意,圖中的地址是從下往上增大的。每一個進程看到的虛擬地址空間由大量準肯定義的區構成,每一個區都有專門的功能。
咱們從最低的地址開始,逐步向上介紹。
程序代碼和數據。 對全部的進程來講,代碼是從同一固定地址開始,緊接着的是和C全局變量相對應的數據位置。代碼和數據區是直接按照可執行目標文件的內容初始化的,在示例中就是可執行文件hello。
堆。 代碼和數據區後緊隨着的是運行時堆。代碼和數據區在進程一開始運行時就被指定了大小,與此不一樣,當調用像malloc和free這樣的C標準庫函數時,堆能夠在運行時動態地擴展和收縮。
共享庫。大約在地址空間的中間部分是一塊用來存放像C標準庫和數學庫這樣的共享庫的代碼和數據的區域。
棧。 位於用戶虛擬地址空間頂部的是用戶棧,編譯器用它來實現函數調用。和堆同樣,用戶棧在程序執行期間能夠動態地擴展和收縮。特別地,每次咱們調用一個函數時,棧就會增加;從一個函數返回時,棧就會收縮。
內核虛擬內存。 地址空間頂部的區域是爲內核保留的。不容許應用程序讀寫這個區域的內容或者直接調用內核代碼定義的函數。相反,它們必須調用內核來執行這些操做。
虛擬內存的運做須要硬件和操做系統軟件之間精密複雜的交互,包括對處理器生成的每一個地址的硬件翻譯。基本思想是把一個進程虛擬內存的內容存儲在磁盤上,而後用主存做爲磁盤的高速緩存。