1. 程式人生 > >讀書筆記——《深入理解計算機系統》第三章_程式的機器級表示(一)

讀書筆記——《深入理解計算機系統》第三章_程式的機器級表示(一)

    前言:已經大四,沒有去找工作,選擇了保研,之所以這樣選擇,有三個原因,一、剛進校時,聽說保研都是牛人才能行的事,所以一心努力保研;二、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

   double 8    longlong 8    char* 8   unsigned long 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(無符號除法)