Linux核心分析作業(1)——電腦是如何工作得?

來源:互聯網
上載者:User

標籤:

根據163MOOC學院中國科學技術大學孟寧孟老師課程所寫得部落格

肖沖沖 原創作品請註明出處

《Linux核心分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000

一,電腦的工作過程

   電腦的基本原理是儲存程式和程式控制(馮﹒諾依曼體系),簡單來說,我們需要先把需要進行操作的指令(程式)和資料先輸入到電腦的存放裝置中,然後電腦將嚴格執行需要執行的指令,包括從那個地址取數(或指令),進行什麼操作(加減移位等),然後再送回到什麼地址。

   從硬體上來說,組成現代CPU的基礎元件的有超大規模的邏輯門,定時器,以及高效能的cache和高精度時鐘。邏輯門提供邏輯仲裁功能,運算器精於各種運算,cache提高資料交換效率。

   從軟體上來說,我認為我們的程式就是與電腦尤其是CPU上面的各種寄存器進行資料互動來使用電腦的硬體功能,比如網路通訊,就是我們的程式使用網路介面進行資料互動。或者最經典的C語言列印“hello world”這個程式,簡單說來就是我們的程式控制CPU相關的寄存器在顯存裡面寫入了“hello world”這個字串顯示的相關指令和資料。在這個過程中,軟體控制硬體目的就是,我們的顯示器上面顯示出了“hello world”,而這一過程本身可以抽象為軟體和顯示裝置之間的資料互動。

   總得來說,在電腦上,軟體承擔著主動向硬體進行資料互動的任務,而硬體是被動的接收和響應處理這些資料(當然你得按照正確的時序來操作還得保證輸入正確的資料)。那麼有沒有硬體是可以主動去做一些事情呢,當然是有得,在ASIC裡面,都是先通過軟體(現在大部分是FGPA級實現)來進行類比驗證,然後再通過純硬體實現相關功能。

   而我們電腦的工作過程,我認為就是軟體操作這些硬體的過程。

   至於如何來操作這些東西,我們需要瞭解CPU的寄存器,基礎的彙編指令等。

   下面我跟著孟老師的課程,反組譯碼一段C語言代碼來簡單介紹下這個過程和涉及的相關知識。

二,彙編代碼工作過程中堆棧過程的變化

    至於如何到實驗樓進行相關實驗,在孟老師的視頻講得非常詳細,這裡略過不表。

我的過程如下:

實驗樓裡面的虛擬機器,使用非常方便。

這個是我們的目標c代碼,很簡單的一段代碼。

編譯命令如下:

1 int g(int x){2     return x + 3;3 }4 int f(int x){5     return g(x);6 }7 int main(void){8     return f(8) + 1;9 }
簡單的C語言代碼

 

使用如下命令產生彙編代碼:

gcc -S -o main.s main.c -m32

注意:此處-m32參數是反編譯成32位的彙編指令,因為實驗樓所提供的虛擬機器是64位的,所以加上該參數。我實驗了下,如果不加入該參數,所得到的指令會摻雜64位的指令。比如movq和pushq等。

所產生的彙編代碼如下(該代碼已經將一些標誌符等進行了刪減以利於分析):

 1 .file    "main.c" 2 g: 3     pushl    %ebp 4     movl    %esp, %ebp 5     movl    8(%ebp), %eax 6     addl    $3, %eax 7     popl    %ebp 8     ret 9 f:10     pushl    %ebp11     movl    %esp, %ebp12     subl    $4, %esp13     movl    8(%ebp), %eax14     movl    %eax, (%esp)15     call    g16     leave17     ret18 main:19     pushl    %ebp20     movl    %esp, %ebp21     subl    $4, %esp22     movl    $8, (%esp)23     call    f24     addl    $1, %eax25     leave26     ret
反編譯出來的彙編代碼

 下面進入正題。

首先來說下幾個基礎點:

1,幾個寄存器的名稱和作用

  • EIP   32位指令寄存器 用於存放下一次需要執行的指令地址,在當前的指令地址被取出之後,會自動的+1
  • EBP  擴充基址指標寄存器其記憶體放一個指標,該指標指向系統棧最上面一個棧幀的底部
  • ESP  棧指標,用於指向棧的棧頂(下一個壓入棧的活動記錄的頂部),而EBP為幀指標,指向當前活動記錄的底部
  • EAX 是一種32位通用寄存器。 EAX寄存器稱為累加器,AX寄存器是算術運算的主要寄存器,所有的輸入、輸出只使用AL或AX人作為資料寄存器

2,函數調用的堆棧是由多個堆棧疊加起來得。我的理解如示,函數example()佔用了如下的一段空間,而它是由函數內的多個棧疊加起來得(由於當初堆棧學得不太好,此處不知道理解得是否正確?):

  

3,函數的傳回值預設由EAX寄存器儲存返回給上一級的函數。

4,pushl %ebp,將當前ebp壓棧同時esp的值被修改。

5,在程式中,

  • ret    =  popl %eip
  • enter = push %ebp

                movl %esp,%ebp

  • leae  =  movl %ebp,%esp

                popl %ebp

下面看具體分析:

 1 .file    "main.c" 2 g:                            ;函數g 3     pushl    %ebp             ;將ebp壓棧,同時esp的值減去4個位元組,棧向下增長一段 4     movl    %esp, %ebp        ;採用寄存器定址的方式,將esp的值賦給ebp 5     movl    8(%ebp), %eax     ;將ebp變址定址加8,將該地址的棧空間儲存的值賦給eax 6     addl    $3, %eax          ;將eax裡面儲存的資料加3,即實現 8 + 3的操作,然後將結果賦值給eax,此時eax=11 7     popl    %ebp              ;將ebp出棧,此時esp加上4個位元組,指向了原先儲存著leavel的棧位置 8     ret                       ;將eip出棧,回退到上一個跳轉時的位置下一段指令,即f函數中的leave處 9     10 f:                            ;函數f11     pushl    %ebp             ;將ebp壓棧,同時esp的值減去4個位元組,棧向下增長一段12     movl    %esp, %ebp        ;採用寄存器定址的方式,將esp的值賦給ebp13     subl    $4, %esp          ;將esp的值減4個位元組,即棧向下再增長一段14     movl    8(%ebp), %eax     ;將ebp變址定址加8,將該地址的棧空間儲存的值賦給eax15     movl    %eax, (%esp)      ;將eax的值賦給esp所指向的地址的棧空間16     call    g                 ;跳轉到函數g,執行之後EIP指向leave的值將會儲存到棧中17     leave                     ;leave指令此時將ebp的值賦值給esp,然後將ebp出棧,然後esp將指向儲存著上一個函數跳轉時的下一段指令,即函數main中的addl處      18     ret                       ;將eip出棧,回退到上一個跳轉時的位置下一段指令,即main函數中的addl處19     20 main:                         ;程式的進入點21     pushl    %ebp             ;將ebp壓棧,同時esp的值減去4個位元組,棧開始向下增長22     movl    %esp, %ebp        ;採用寄存器定址的方式,將esp的值賦給ebp23     subl    $4, %esp          ;將esp的值減4個位元組,即棧向下增長一段24     movl    $8, (%esp)        ;對esp所指向的棧空間賦值為825     call    f                 ;跳轉入函數f,轉向f段代碼,此時EIP指向函數f26     addl    $1, %eax          ;將eax中的值加1並存入eax,此時eax = 1227     leave                     ;此時將ebp的值賦值給esp,然後esp將指向棧尾0,然後將ebp出棧,同樣ebp也將指向棧尾028     ret                       ;將eip出棧,因為沒有下一條指令,程式至此執行完畢。
彙編代碼中堆棧的變化 時間不多了,後續補充一個流程圖來詳細描述該堆棧過程。該篇文章裡面也許會有很多錯誤的地方,尤其最後組譯工具堆棧分析,我應該還沒能完全理解孟老師的意思,懇請各位指正,互相交流學習。

Linux核心分析作業(1)——電腦是如何工作得?

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.