這章通過乙個hello
程式的生命週期開始對系統的學習。這章將會學習一些實踐技巧,例如避免由計算機表示數字的方式導致的奇怪的數字錯誤;將會學習優化
c**的竅門,以充分利用處理器和儲存器系統的設計;將了解到編譯器是如何實現過程呼叫的,以及如何避免緩衝區溢位錯誤帶來的安全漏洞;將會學習如何編寫自己的
unix
外殼、動態儲存分配包、
web伺服器,認識到併發帶來的希望和陷阱。
hello.c源程式:
#include
int main()
printf(「hello,world\n」);
hello程式的生命週期從源程式開始,源程式是由0和1
組成的位(bit)
序列。8個位被組織成一組,稱為位元組。每個位元組表示程式中的某個文字字元,一般用ascii
標準來表示,即用乙個唯一的單位元組大小的整數值來表示每個字元。
hello程式以位元組序列的方式儲存在檔案中,每個位元組都有乙個整數值。每個文字行都以乙個不可見的換行符』\n』結束,對應整數值為10
。只由ascii
字元構成的檔案稱為文字檔案,其他檔案都稱為二進位制檔案。
基本思想:系統中所有資訊——包括磁碟檔案、儲存器中的程式、儲存器中存放的使用者資料以及網路上傳送的資料,都是由一串位表示的。區別不同資料物件的唯一方法是上下文。不同的上下文中,同樣的位元組序列可能表示乙個整數、浮點數、字串或者機器指令。
其他程式 按可執行目標程式格式打包,並以二進位制磁碟檔案存放
高階語言程式語句-------->
機器語言指令
------------------------------------>
可執行目標檔案
編譯:gcc -o hello hello.c
編譯系統如圖所示:
·預處理階段:預處理器根據以字元#
開頭的命令修改原始的
c程式。以
.i作為副檔名。
例如:#include
命令告訴預處理器讀取系統標頭檔案
stdio.h
的內容並插入到程式文字中,得到另乙個c程式
hello.i。
·編譯階段:編譯器將hello.i
翻譯成hello.s
,包含乙個組合語言程式。
·彙編階段:彙編器將hello.s
翻譯成機器語言指令,並將指令打包成可重定位目標程式的格式,將結果儲存在
hello.o
中。hello.o
是乙個二進位制檔案,位元組編碼是機器語言指令而不是字元。
·鏈結階段:鏈結器處理合併,得到可執行目標檔案,可以被載入到記憶體中,由系統執行。
例如:hello
程式中呼叫了
printf
函式,它是標準庫里的函式,存在於乙個
printf.o
的預編譯好的目標檔案中,鏈結器將這個檔案合併到
hello.o
檔案中,得到
hello
檔案。要在系統上執行可執行檔案,將其檔名輸入到外殼中:
unix> ./hello
hello,world
unix>
外殼是乙個命令列直譯器,輸出提示符,等待輸入乙個命令列,執行命令。
3.1 系統的硬體組成
cpu:**處理單元。
alu:算術/
邏輯單元。
pc:程式計數器。
usb:
通用序列匯流排
1.匯流排
貫穿整個系統的一組電子管道。匯流排攜帶資訊位元組並負責在各個部件之間傳遞。通常匯流排傳送定長的位元組塊(字)。字中的位元組數是乙個基本的系統引數。32
位的字長是
4個位元組,
64位的是
8個位元組。假設字長為
4個位元組,且匯流排每次只傳送乙個字。
2.i/o裝置
系統與外部世界的聯絡通道。例項中包括鍵盤,滑鼠,顯示器,磁碟驅動器。每個i/o
裝置通過乙個控制器或者介面卡與i/o
匯流排相連。控制器是主機板上的晶元組,介面卡是插在主機板插槽上的卡,功能都是在
i/o匯流排和
i/o裝置之間傳遞資訊。
3.主存
臨時儲存裝置,在處理器執行程式時,用來存放程式和程式處理的資料。主存是由一組動態隨機訪問儲存器(dram
)晶元組成的。儲存器是乙個線性的位元組陣列,每個位元組都有唯一的位址(陣列索引),位址從0
開始。c
程式變數對應的資料項的大小是根據型別變化的。例如
32位機器上,
short
型別的資料需要
2個位元組,
int、
float
、long
型別需要
4個位元組,
double需要8
個位元組。
4.處理器(**處理單元cpu)
解釋或執行儲存在主存中指令的引擎。核心是乙個字長的儲存裝置(暫存器),稱為程式計數器(pc
)。pc
在任何時刻都指向主存中的某條機器語言指令(含有該條指令的位址)。從系統通電開始到斷電期間,處理器不斷地從
pc指向的儲存器處讀取指令,解釋指令中的位,執行指令指示的簡單操作,再更新
pc,使其指向下一條指令,下一條指令不一定與剛剛執行的指令相鄰。
操作圍繞主存、暫存器檔案、算術/
邏輯單元(
alu)進行。暫存器檔案是小的儲存裝置,由1
字長的暫存器組成,每個暫存器都有唯一的名字。
alu計算新的資料和位址值。
cpu可能會執行以下操作:
·載入:把乙個位元組或乙個字從主存複製到暫存器,以覆蓋暫存器原來的內容。
·儲存:把乙個位元組或乙個字從暫存器複製到主存的某個位置,以覆蓋這個位置上原來的內容。
·操作:把兩個暫存器的內容複製到alu,alu
對這兩個字做算術操作,並將結果存放到乙個暫存器中,以覆蓋暫存器原來的內容。
·跳**從指令本身中抽取乙個字,並將這個字複製到pc
中,以覆蓋
pc中原來的值。
指令集結構描述的是每條機器**指令的效果,微體系結構描述的是處理器是如何實現的。
3.2 執行
hello程式
初始時,外殼程式執行它的指令,等待我們輸入乙個命令,當我們在鍵盤上輸入字串後,外殼程式將字元逐一讀入暫存器,再把它存放到儲存器中。
當我們敲回車鍵時,外殼知道我們已經結束了命令的輸入,外殼執行一系列指令來載入可執行的hello
檔案,將檔案中的**和資料從磁碟複製到主存,資料報括最後輸出的字串(利用直接儲存器訪問dma
,資料可以不通過處理器而直接從磁碟到達主存)。當**和資料被載入到主存,處理器開始執行hello
程式的main
程式中的機器語言指令,指令將字串的位元組從主存複製到暫存器檔案,再從暫存器檔案中複製到顯示裝置,最終顯示在螢幕上。
深入理解計算機系統第一章
即每個程式中的每個字元都在ascii標準中被乙個具體的數值來標明。這些字元稱之為ascii字元,由ascii字元構成的檔案叫做文字檔案,其他都是二進位制檔案 從原始檔到目標檔案需要4個階段,預處理,編譯,彙編,鏈結。系統的硬體組成 匯流排 貫穿系統的是一組電子管道,稱為匯流排,它攜帶資訊位元組並負責...
《深入理解計算機系統》第一章 計算機系統漫遊
計算機系統是由硬體和系統軟體組成的,他們共同工作來執行應用程式。深入理解底層計算機系統以及它對應用程式的影響有助於提高程式的效能。1.1 資訊就是位 上下文 源程式實際上就是乙個由值0和1組成的位序列。程式是由文字字元表示的,8個位被組織成一組,成為位元組,每個位元組表示為程式中的文字字元。文字字元...
深入理解計算機系統 第一章 計算機系統漫遊
本著對計算機執行原理的好奇以及個人職業發展的需要,開始閱讀這本書。以下分節記錄讀書筆記 1.1 資訊就是位 上下文 計算機系統中存放的所有資訊都是由一串位元 bit 表示的,但值得注意的是,同樣的位元資訊在不同的上下文中所代表的意思是不同的。在這裡,我們可以將 上下文 理解為對位元資訊的解讀方式。每...