深入理解計算機系統 程式的機器級表示

2021-07-22 18:32:51 字數 2366 閱讀 8613

本章基於兩種相關的機器語言:intel ia32和x86-64。前者是32位計算機上的語言,後者是前者在64位機器上的拓展。

32位計算機的虛擬記憶體有4gb,而64位計算機高達256tb。

假設乙個c程式有兩個檔案p1.c和p2.c,在32位計算機上用unix命令列編譯這些**如下:

unix> gcc -01 -o p p1.c p2.c
命令gcc就是linux上的預設編譯器:gcc c。編譯選項-01告訴編譯器使用第一級優化。

gcc命令呼叫了一系列程式,將源**轉化成可執行**。

首先,c預處理器拓展源**,插入所有用#include 命令指定的檔案,並拓展所有用#define宣告指定的巨集。

然後,編譯器產生兩個源**的彙編**,名字分別是p1.s和p2.s。

接下來,組合語言將彙編**轉換成二進位制目標**,檔名為p1.o和p2.o。目標**是機器**的一種形式,它包含所有指令的二進位制表示,但是還沒有填入位址的全域性值。

最後,鏈結器將兩個目標**檔案與實現庫函式(例如printf)的**合併,並產生最終的可執行**檔案p。

ia32機器**和原始的c**差別非常大,一些通常對c語言程式設計師隱藏的處理器狀態是可見的:程式計數器(在ia32中用%eip表示)、整數暫存器檔案、條件碼暫存器等。

在命令列上使用「-s」選項,就能得到c語言編譯器產生的彙編**:

unix> gcc -01 -s code.c
這會使gcc執行編譯器,產生乙個彙編檔案code.s,但是不做其他進一步的工作。

如果我們使用「-c」命令列選項,gcc會編譯並彙編該**:

unix> gcc -01 -c code.c
這就會產生目標**檔案code.o,它是二進位制格式,所以無法直接檢視。機器實際執行的程式只是對一系列指令進行編碼的位元組序列,機器對產生這些指令的源**一無所知。

要檢視目標**檔案的內容,最有價值的是反彙編器,它是基於機器**檔案中的位元組序列來確定彙編**。

int main()
然後,用如下方法生成可執行檔案prog:

unix> gcc -01 -o prog code.o main.c
生成的prog不僅包含兩個過程的**,還包含了用來啟動和終止程式的資訊,以及用來與作業系統互動的資訊。

c語言提供了多種迴圈結構,即do-while、while和for。彙編中用條件測試和跳轉結合起來實現。大多數彙編器根據乙個迴圈的do-while形式來產生迴圈**,即使do-while的形式用得相對較少。其他的迴圈會首先轉換成do-while形式,然後再編譯成機器**。首先從do-while開始。

do-while的通用形式可以翻譯成如下所示的條件和goto語句:

loop:

body-statement

t=test-expr;

if(t)

goto loop;

每次迴圈,程式會執行迴圈體內的語句,然後執行測試表示式。如果測試為真,則回去再執行一次迴圈。

將while迴圈翻譯成機器**有很多種方法,常見的是使用條件分支,在需要時省略迴圈體的第一次執行,從而將**轉換成do-while迴圈,如下:

if(!test-expr)

goto done;

do body-statement

while (test-expr);

done:

接下來,這個**可以直接翻譯成goto**,如下:

t=test-expr;

if(!t)

goto done;

loop:

body-statement

t=test-expr;

if(t)

goto loop;

done:

for迴圈可以很容易轉換成while迴圈,進而轉換成do-while形式:

init-expr;

if(!test-expr)

goto done;

do while (test-expr);

done:

然後,將它轉換成goto**:

init-expr;

t=test-expr;

if(!t)

goto done;

loop:

body-statement

update-expr;

t=test-expr;

if(t)

goto loop;

done:

《深入理解計算機系統》 系統級I O

關於i o可以先參考這些文章,但是這裡可能還是有所不同。分析系統級別的i o有什麼不一樣的地方。檔案i o 高階i o 標準庫i o 開篇介紹了三個級別的i o的區別之處。所有語言的執行時系統都提供執行i o的較高階別的工具。例如,標準i o庫 在unix系統中,是通過使用由核心提供的系統級i o函...

深入理解計算機系統

關鍵路徑是在迴圈的反覆執行中形成的資料相關鏈。迴圈展開是一種程式變換,通過增加每次迭代計算的元素的數量,減少迴圈的迭代次數。重新結合變換能夠減少計算中關鍵路徑上操作的數量,通過更好地利用功能單元的流水線能力得到更好的效能。浮點運算不保證是可結合的,通常迴圈展開和並行地累積在多個值中,是提高程式效能的...

《深入理解計算機系統》

知乎 深入理解計算機系統 這本書需要什麼水平能看懂?15 213 18 218 15 513 introduction to computer systems schedule fall 2016 鏈結失效則 cmu15 213的課程主頁,有ppt,還有錄影,主講人就是這本書的作者。備註 備註 詳細...