標籤:
本文轉載地址:http://www.cnblogs.com/zuoxiaolong/p/computer14.html
引言
本文的內容其實可以成為組合語言的基礎,因為組合語言大部分時候是在操作一些我們平時開發看不到的東西,因此本文的目的就是搞清楚,組合語言都是在操作些什麼東西。或者更準確的說,各種彙編指令都是在操作什麼樣的對象。
彙編層次的對象
在平時的開發過程中,CPU處理器的狀態對開發人員是隱藏的,我們看不到CPU當中各個對象的狀態。但是在組合語言中,我們可以清楚的看到這些對象的狀態,其中CPU主要包含以下幾個對象。
程式計數器(PC):記錄下一條指令的地址。
整數寄存器檔案:共8個,可以儲存一些地址或者整數的資料。
條件寄存器:儲存算數或邏輯指令的狀態資訊,可以實現程式的流程式控制制。
浮點寄存器:儲存浮點數。
可以看出,這些都是CPU處理器當中的對象,上一章我們寫過一個簡單的C程式,相信如果不是看了彙編代碼,各位也都看不出來在程式運行過程中,CPU當中這些對象都在做著一些什麼樣的操作,又在儲存著一些什麼樣的內容。
資料的格式
在上一章當中,幾乎所有的彙編指令後面都有一個字母l,比如movl、addl、subl、pushl等等,這個l的尾碼其實就是表示的資料格式,表示我們操作的是32位的數值。
在電腦從16位擴充到32位,以至於當前的64位來講,資料格式就一直在變。但是曆史總會多少影響著未來的走向,因此我們習慣稱16位為“字”,而32位則為“雙字”,相應的,64位則為“四字”。
以下我們以IA32架構為例,來看一下各個資料格式對應的尾碼是什麼。
圖當中已經介紹的比較清楚,LZ這裡就不再廢話了。需要一提的就是,long long int在IA32架構中是不支援這種資料格式的,因此就沒有列出它的尾碼。另外,long double是一種擴充類型,通常採用12個位元組來表示。
上面的圖示使用的方式很簡單,比如mov指令,它是一個資料傳送的指令,那麼movb就代表傳送一個位元組的資料,movw就代表傳送兩個位元組的資料,而movl就代表傳送四個位元組的資料。
寄存器
寄存器是CPU當中非常重要的對象,一般情況下,很多臨時變數都會儲存在這裡,就像上一章當中的臨時變數t,在最佳化之後,t將不再進入主存,而只留在寄存器當中。這樣可以提高程式啟動並執行速度,因為寄存器的速度要高於主存,而且在寄存器與主存之間傳輸資料,也是十分耗時間的一件事。
下面是一張書中的寄存器圖示,它基於IA32架構給出。
可以看到,對於%esp和%ebp寄存器來講,圖中標註了它們分別是棧指標以及幀指標。而對於另外六個寄存器來講,它們大部分時候是一樣的,但是還是有些許的不同。
比如%eax寄存器,它很多時候用來儲存函數的傳回值。而對於%eax、%ecx、%edx、%ebx來講,它們都可以被訪問單獨的位元組。另外需要一提的是,這八個寄存器都可以被訪問雙位元組。
除了以上的區別之外,對於%eax、%ecx、%edx和%ebx、%esi、%edi來講,它們的使用慣例也有些許不同,這個在後面我們將深入討論。這裡各位只要大概認識一下這八位神仙就行了。
運算元指示符
運算元指示符這個稱謂是書上給的,但LZ覺得這個概念不太容易理解,運算元指示符其實指的就是一種取值的標識方式,用來擷取參與各種操作的運算元。
這些標識方式一共有三種,一種是$符號後跟一個標準C表示的整數,比如$100,$0x11等等。第二種則是寄存器,當它作為一個運算元的時候,則是取的寄存器當中的數值。另外,對於寄存器來說,也可以選擇性的操作4個、2個、1個位元組,而並不一定非要操作4個位元組。最後一種,則是我們相對來說最熟悉的,就是儲存空間或者說記憶體。當它作為一個運算元的時候,會去計算儲存空間地址的數值,然後去這個地址取相應的數值。
對於這三種運算元的標識方式,在書中給出了一個表格,這裡LZ貼一下。
第一列是代表的類型,而第一行則是指的立即數,第二行則是指的寄存器,而剩下的都是儲存空間了。對於立即數和寄存器來講,比較好理解,就是直接取值或者取寄存器的值。而對於儲存空間來講,則有很多種情況,不過我們也可以看出,上面所有的情況,其實都是最後一種的特殊情況。Imm(Eb,Ei,s)是儲存空間取值的一般形式,比如當Imm為0時,則是倒數第二種取值方式。對於其它的形式,也可以使用同樣的方式推算出來。
由於儲存空間相對來說,理解起來比較困難一點。因此這裡LZ舉個簡單的例子,比如對於4(%esp,%eax,4)這個運算元來講,它代表的是記憶體位址為4+%esp+4*%eax的儲存空間地區的值。
運算元是大部分指令都有的,因此上面的這些標識方式,在之後的文章中我們會經常看到,它們將會成為各位猿友很好的朋友。
文章小結
本章只介紹了一些彙編當中基礎的知識,這些內容相對來講不是特別困難,但卻是開啟後面神秘大門的鑰匙。因此倘若有哪位猿友不是太理解本章的內容的話,LZ希望各位可以從實踐入手去理解一下本章的內容。這一點可以結合上一章來看,從上一章給出的彙編代碼中尋找資料格式、運算元以及寄存器的部分,這應該是十分輕鬆的,因為上一章的彙編代碼中充斥著這三個部分的內容。
深入理解電腦系統(3.2)---資料格式、訪問資訊以及運算元指示符