1. 程式人生 > >20189220 余超《Linux內核原理與分析》第二周作業

20189220 余超《Linux內核原理與分析》第二周作業

運行 角度 出棧 要求 刪除 基礎知識 默認 學會 步驟

計算機如何工作的

一.存儲程序計算機工作模型

馮諾依曼體系結構:核心思想為存儲程序計算機。兩個層面:
(1)硬件的角度(計算機主板):一個CPU,一塊內存,之間有總線連接。CPU內部有一個IP計算器,IP指向內存中的指令,並依次加一執行;

(2)另一個層面,程序員的角度:存儲程序計算機工作模型(如下圖)
技術分享圖片

  • 解釋:CPU抽象為for循環,總是執行下一條指令,內存保存指令和數據,CPU來解釋和執行這些指令。
  • API:應用程序編程接口(程序員與計算機的接口界面)。

  • ABI:二進制接口,指令編碼(程序員與CPU的接口界面)。

二.計算機的匯編指令:

  • (1)movl指令(32位):
    寄存器尋址,寄存器模式,以%開頭的寄存器標示符。不和內存打交道,eax賦值給edx;

立即尋址,把立即數直接放在寄存器,立即數是以$開頭的數值;

直接尋址,直接訪問一個指定的內存地址的數據;

間接尋址:將寄存器的值作為一個內存地址來訪問內存;

變址尋址:在間接尋址之時改變寄存器的數值。

  • (2)其他指令(32位):
    pushl 壓棧,esp減4,把eax放入esp內存位置

popl 出棧,從堆棧棧頂取32位放到寄存器eax裏面,有兩個動作:首先間接尋址,把棧頂數值放到eax裏面,再把棧頂加4。

call 函數調用,把當前的eip壓棧,給eip賦新值;

註意:*是指這些指令是偽指令,程序員不能直接修改這些,即eip寄存器不能被直接修改,只能通過特殊指令間接修改。

三.匯編一個簡單的C程序分析其匯編指令執行過程

簡單的c語言程序:
技術分享圖片

輸入gcc –S –o 20189220main.s 20189220main.c -m32 ,刪除多余的代碼從而形成匯編代碼,如圖:
技術分享圖片

  • esp:寄存器存放當前線程的棧頂指針
  • ebp:寄存器存放當前線程的棧底指針
  • eip:寄存器存放下一個cup指令存放的內存地址,當cpu執行完成當前指令之後,從eip寄存器中讀取下一條指令的內存,然後繼續執行。
  • eax:暫存一些數值,函數的返回值通過eax默認返回給上級函數(32位x86)。

四.闡述堆棧的變化過程:

當開始執行改程序的時候,eip是指向main函數入口地址,即eip指向18行存放的指令。設默認的堆棧棧低寄存器ebp的值為1000,則堆棧棧頂指針也為1000。

1、pushl %ebp: 把ebp的值壓入堆棧,esp=996,棧頂值為1000

2、movl %esp,%ebp: 將esp的值傳給ebp,則ebp值為996

3、subl $4,%esp:將esp的值減去4,則esp的值為992

4、movl $24,(%esp): 將esp所指的值為地址(寄存器間接尋址)的值 賦為6(堆棧的棧頂存放6)
此時堆棧:
技術分享圖片

5、call f:相當於pushl eip和movl f eip。堆棧先壓入eip(23),esp=esp-4=988。然後把f函數的入口函數地址賦值給eip(存放第9行的指令代碼)
此時堆棧:
技術分享圖片

6、pushl %ebp: 在堆棧中壓入ebp的值,esp=esp-4=984

7、movl %esp,%ebp: 把esp的值賦給ebp。ebp=esp=984

8、subl $4,%esp: 把esp的值減去4。esp=esp-4=980

9、movl 8(%ebp),%eax: 把ebp+8的地址上所存的值賦給eax,即把地址為992,值為6賦值給eax寄存器

10、movl %eax,(%esp): 相當於壓棧
此時堆棧:
技術分享圖片

11、call g: 相當於pushl eip和movl g eip。棧堆先壓入eip(15),在把函數g的入口地址賦給eip
此時堆棧:
技術分享圖片

12、pushl %ebp: 堆棧壓入ebp的值

13、movl %esp,%ebp: 把esp的值賦給ebp

14、movl 8(%ebp),%eax: 將ebp的值加8作為地址,其值賦給eax。即,eax值為6

15、addl $4,%eax: 將eax的值加4。eax的值為10

16、popl %ebp:堆棧彈出,其值賦給ebp。
此時堆棧:
技術分享圖片

17、ret : 相當於popl %eip(*)。堆棧彈出,其值賦給eip。則eip指向了存儲15行代碼的地址。
此時堆棧:
技術分享圖片

18、leave: 相當於movl %ebp,%esp和popl %ebp。將ebp的值賦給esp,堆棧彈出,其值賦給ebp。相當於銷毀g的函數堆棧意思。esp=988,ebp=996。
此時堆棧:
技術分享圖片

19、ret : 相當於popl %eip(*)。堆棧彈出,其值eip(23)賦給eip
技術分享圖片

20、addl $2,%eax: 把eax的值加上2,eax的值為10+2=12。

21、leave :相當於movl %ebp,%esp和popl %ebp。將ebp的值賦給esp,堆棧彈出,其值賦給ebp。相當於銷毀f的函數堆棧意思。esp=1000,ebp=1000
此時堆棧:
技術分享圖片

總結:

  • 本周通過學習計算機匯編的基礎知識和基本原理,理解到了計算機的基本原理存儲程序和程序控制。
  • 預先要把指揮計算機如何進行操作的指令序列(稱為程序)和原始數據通過輸入設備輸送到計算機內存貯器中。每一條指令中明確規定了計算機從哪個地址取數,進行什麽操作,然後送到什麽地址去等步驟。
  • 計算機在運行時,先從內存中取出第一條指令,通過控制器的譯碼,按指令的要求,從存儲器中取出數據進行指定的運算和邏輯操作等加工,然後再按地址把結果送到內存中去。接下來,再取出第二條指令,在控制器的指揮下完成規定操作。依此進行下去。直至遇到停止指令。程序與數據一樣存貯,按程序編排的順序,一步一步地取出指令,自動地完成指令規定的操作是計算機最基本的工作原理。
  • 這只是一個簡單的程序,在後面的學習中要把老師介紹的深入理解計算機系統的第三章程序的機器級表示的內容再看一看,學會用計算機的思維來進行思考和編程。

20189220 余超《Linux內核原理與分析》第二周作業