讀書筆記——《深入理解計算機系統》第三章_程式的機器級表示(一)
前言:已經大四,沒有去找工作,選擇了保研,之所以這樣選擇,有三個原因,一、剛進校時,聽說保研都是牛人才能行的事,所以一心努力保研;二、2008年開始,經濟危機比較嚴重,工作不好找,雖然軟體專業要找一份工作還是比較容易,但好工作的機會少了很多,再多學習幾年,規避下風險;三、三年多的本科學習下來,雖然簡歷看起來還像回事,但內心很虛,感覺真才實學沒多少,都是略懂皮毛,做了太多表面工作,沒有特長,選擇讀研,希望在某一方面能夠深入學習,不再流於膚淺,真正地學有所長。
保研成功後,過了近一個月豬一樣的生活,實在過得空虛,看到考研同學每天辛苦地備考,在暗自慶幸的同時,也意識到,保研給我節約了很大一筆時間,不應該把這段時間荒廢了。於是找了譚師兄和樑老師,讓他們給我指點一二。樑老師的建議很中肯,他說如果他現在是HR,他會只招本科生,而不是研究生,因為現在研究生的質量比本科生高不到哪裡去,而且一把年紀了,本科生出來工作三年後經驗什麼的都要比研究生強多了,說不定很多本科生還會當研究生的思想導師。這個說法當然比較絕對,但是我認為還是很有道理,因此,他說,你如果去讀研,就不要再像本科一樣把自己定位為一個coder,而應該至少是去做一個提出解決方案的,具體的實現讓下面的人去做。你可以發現很多好東西好的解決方案都是老外提出來的,為什麼中國人只能錦上添花,那裡因為我的的基礎知識不夠紮實,知識體系不夠健全,連自己手中的計算機是怎麼工作的都不知道,怎麼能提出很好的解決方案呢。所以,對於大四這一年,他給我推薦了兩本書,一本《深入理解計算機系統》,這本書很基礎,但是覆蓋面很全,可以幫助加深對計算機的理解,知道它底層是怎麼工作的,健全計算機體系的知識,而不是隻學一些程式設計技術之類的表相的東西,這樣永遠只會被別人牽著走;另外一本書是《Unix環境高階程式設計》,他說你以後是去做網路方面的東西,而網路是絕對離不開Unix,你把這本書的程式當模板背下來以後,第一、程式設計就不成問題,第二、可以對Unix有全面的瞭解。
好記性不如爛筆頭,看了書不能過了了事,遂做此讀書筆記,僅為學習溫習之用,高手勿笑:)
前言囉嗦完畢,迴歸正文:
3.3資料格式(記住)
- 由於是從16位體系結構擴充套件成32位,intel用術語字(word)表示16位資料型別,因此32位為雙字(double words),64位數為4字(quad words)。
- 以下是比較容易模糊的資料型別大小:
32位機上:float 4 long int 4 double 8 longlong 8 char* 4 unsigned long 4
64位機上:float 4 long int 8
另外,GCC 用long double表示擴充套件精度(10位元組),出於儲存器效能考慮,會被儲存為12位元組
3.4訪問資訊
- 一個IA32 CPU包含一組8個儲存32位值的暫存器,用以存整數資料和指標:eax,ecx,edx,ebx,esi,edi esp,ebp。大多數情況下前六個都用作通用暫存器,eax,ecx,edx的儲存和恢復慣例不同於ebx,edi,esi(前三者為被呼叫者儲存,後三者為呼叫者儲存,詳見3.7.3);最後兩個用於儲存指標,由於在過處理中非常重要,分別指向棧幀的頂部和底部,必須保持。
3.4.1運算元指示符(記住)
大多數指令有一到多個運算元,運算元有三種:
立即數:即常數值
暫存器:表示某個暫存器內容
儲存器引用:根據計算出來的地址(通常稱有效地址)訪問某個儲存器位置
因此定址方式也有多種,如:立即數定址、暫存器定址、絕對定址、間接定址、變址定址、伸縮化 的變址定址……
3.4.2資料傳送指令(記住)
幾個重要資料傳送指令:mov族(之所以稱這為族是因為mov指令還有很多兄弟指令如movb、movw、movsb、movzb,這是我個人對它們的稱呼,便於記憶mov其他幾個比較低調的兄弟)、pop、push。
另,對於mov族,movb、movw自不必做過多解釋,movsb、movzb分別為符號擴充套件、零擴
展,它們只拷貝一個位元組,源運算元均為單位元組,並設定目的運算元中其餘的位,效果如下:
初始假設:%dh=8D %eax=98765432
1 movb %dh,%al ;%eax=9876548D
2 movsbl %dh,%eax ;%eax=FFFFFF8D(目的運算元高24位設為源位元組最高位,在這裡為很顯然為1,所以前24位為全F)
3 movzbl %dh,%eax ;%eax=0000008D(目的運算元高24位被設為0)
對於pushl指令等價於:
subl $4,%esp
movl %ebp,(%esp) //注意這裡的括號引起的差別
popl指令等價於:
movl (%esp),%eax
addl $4,%esp
3.4.3資料傳輸例項(理解)
通過彙編程式碼可以得到兩點收穫:
1、指標其實是地址,間接引用指標就是將該指標放在一個暫存器中 ,然後在間接儲存器引
用中引用這個暫存器
2、區域性變數通常儲存在暫存器中,而不是儲存器(個人猜測應該是區域性變數屬於動態
分配,區域性變數因此被動態置入暫存器,而非儲存器)
3.5算術和邏輯操作(看看便可,不必深究)
這類操作符大致分為四個小類:
1、載入有交地址(leal),通常用來執行簡單算術操作,目前還不太懂這個與mov的區別
2、一元或二元操作:incl decl negl notl addl subl imull xorl orl andl
3、移位操作 :sall==shll(填0) sarl(算術右移,填符號位) shrl(邏輯右移,填0)
4、特殊算術操作:imull(有符號64位乘法) mull(無符號64位乘法) cltd(轉換為四字)
idivl(有符號除法) divl(無符號除法)