1. 程式人生 > >第三章 機器的程式級表示

第三章 機器的程式級表示

計算機執行機器程式碼,用位元組序列編碼低階的操作。彙編程式碼是機器程式碼的文字表示。

程式編碼:

linux> gcc -Og  -o p p1.c p2.c

命令gcc即GCC C編譯器。使用gcc命令將原始碼轉換成可執行程式碼。首先,C前處理器擴充套件原始碼,插入所有用#include命令指定的檔案,並擴充套件所有用#define宣告指定的巨集。其次,編譯器產生兩個原始檔的彙編程式碼,分別為p1.s p2.s。接下來,彙編器會將彙編程式碼轉換成二進位制目標檔案程式碼p1.o p2.o。此時,它還沒有填入全域性值的地址。最後,連結器將兩個目的碼檔案和實現庫函式程式碼合併,併產生最終的可執行程式碼檔案p。

 

機器級程式碼:

第一種抽象,由指令集體系結構或指令集架構來定義機器級程式的格式和行為,它定義了處理器狀態、指令的格式以及每條指令對狀態的影響;如,程式計數器、整數暫存器檔案、條件碼暫存器、向量暫存器;

第二種抽象,機器級程式使用的記憶體地址是虛擬地址,機器程式碼將記憶體看成是一個非常大的、按位元組定址的陣列;

程式記憶體包含:程式的可執行機器程式碼,作業系統需要的一些資訊,用來管理過程呼叫和返回的執行時棧,以及使用者分配的記憶體塊。

 

使用-S可以看到C語言編譯器產生的彙編程式碼:

linux-> gcc -Og -S mstore.c   

使用-c,GCC會編譯並彙編該程式碼,產生目標檔案mstore.o,它是二進位制格式,無法直接檢視。上述彙編指令對應的目的碼(位元組序列16進製表示):

總結:機器執行的程式只是一個位元組序列,它是對一系列指令的編碼,機器產生這些指令的原始碼幾乎一無所知。

 

檢視機器程式碼內容:利用反彙編器,根據機器程式碼生成一種類似於彙編程式碼的格式。

objdump -d命令,可以進行反彙編:

linux-> objdump -d mstore.o 

 

 資料格式:

字:16位資料型別

雙字: 32位數

四字:64位數

資料傳送指令分為四種:movb(傳送位元組)、movw(傳送字)、movl(傳送雙字)、movq(傳送四字)

 

訪問資訊:

最初8086中是8個16位的暫存器(%ax到%bp)->擴充套件成8個32位暫存器(%aex到%ebp)->增加8個新的暫存器(%r8到%r15)。如下圖所示:位元組集操作可以訪問最低的位元組,16位操作可以訪問最低的兩個位元組,32位可以訪問最低的4個位元組,而64位可以訪問整個暫存器。

運算元指示符:

運算元分為3種類型:

第一類:立即數,表示常數值,$後跟一個整數,如$-577或$0x1F。

第二類:暫存器,它表示暫存器內容,16個暫存器的低位1位元組、2位元組、4位元組、8位元組中的一個作為運算元。用符號表示任意暫存器a,引用來表示它的值。

第三類:記憶體引用,它會根據計算出來的地址訪問某個記憶體位置。將記憶體看成很大的位元組陣列,符號表示對儲存在記憶體中從地址Addr開始的b個位元組值的引用。

如圖,有多種不同的定址模式,允許不同形式的記憶體引用。引用有四個組成部分,一個是立即數偏移