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
此時堆疊:

總結:

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