計算機是如何工做的?--經過彙編一個簡單的C程序,分析彙編代碼理解計算機是如何工做的

王康 原創做品轉載請註明出處 《Linux內核分析》MOOC課程 http://mooc.study.163.com/course/USTC-1000029000

 

1 存儲程序計算機模型

cpu內部有寄存器ip,分別在16位叫 ip 32 eip 64riplinux

ip經過總線指向代碼段一個地址,取過來一條指令執行;程序員

執行完以後ip取下一條指令自加一繼續指向。編程

硬件來看:馮諾依曼通用小程序

軟件程序員來看:函數

wps246.tmp

內存存儲指令和數據,cpu執行指令spa

cpu識別什麼樣的指令?操作系統

API:程序員與計算機接口界面.net

ABI:二進制接口,程序與CPU接口界面---彙編指令---3d

----指令中涉及一個寄存器,內存地址指針

wps247.tmp

1 eip自加一,是加一條指令而不是地址加一(由於指令長度可能不一樣);

2 eip能夠被CALL,RET,JMP指令能夠修改eip

注意:
1.程序員不能夠直接修改IP的值,只能經過一些指令,如CALL、RET、JMP等間接修改IP的值
2.IP在32位機器中表示爲eip(本次實驗以32位做爲分析),在64位機器中表示爲rip。

 

 

2 x86彙編基礎

wpsF7E3.tmp

開頭e爲32位 ebx+ecx偏移地址  ebp esp堆棧  

以上爲通用寄存器,還有段寄存器

wpsF7E4.tmp

wpsF7E5.tmp

還有一個標誌寄存器

wpsF7E6.tmp

wpsF7E7.tmp

64位差異不大,通用寄存器擴展到64位,前邊帶R就是擴展了的

還增長了一些64位的MMX的寄存器。

使用只是寄存器名字不同,機制差異不大

wpsF7E8.tmp

movl 32位 movb8位 movw16位 mowq 64位

wpsF7F9.tmp

wpsF7FA.tmp

$0x123 16進制的數值放到edx裏邊,也和內存沒有關係

wpsF7FB.tmp

沒有$就表示一個地址放到,後邊就是c語言相同表示:

wpsF7FC.tmp將0x123數值強制轉化爲32位的一個int變量指針,再用*取他指向的值

wpsF7FD.tmp

能夠看到c語言模式同樣的,也是轉地址

wpsF7FE.tmp

wpsF7FF.tmp

wpsF800.tmp

wpsF801.tmp

push 把eax壓倒堆棧棧低,等同於:esp是堆棧棧低,減4,4字節就是32位,且堆棧是向下增加。最後把eax壓入

wpsF812.tmp

pop:把棧頂數值放入eax,而後把esp加四,向上回退

wpsF813.tmp

call:把當前eip壓棧保存起來,賦了一個新值

wpsF814.tmp

ret:pop eip實際就是執行了一個call,call到了函數定義的位置。

pop就是把call時候保存的eip再返回到eip指令當中來,繼續執行當時函數調用的下下一跳指令.

(*)意思是僞指令,不能被程序員直接修改

wpsF815.tmp好比call指令,ret指令

push eip(*)意思是把當前eip值壓入;而ret: pop eip時候會把彈出的值自動賦值到eip寄存器

 

 

3 彙編一個簡單的c程序分析其彙編指令執行過程

wps49BB.tmp

吧當前main.c編譯爲32位。-S爲生成編譯文件

main.s全部用.開頭是鏈接時候輔助信息

wps38EE.tmpwps38EF.tmpwps38F0.tmp

wps38F1.tmp

wps49CC.tmp

wps49CD.tmp

wps49CE.tmp

這兩條能夠認爲是宏指令,一個是函數調用一個是函數退出,正好相反

wps49CF.tmp

wps49D0.tmp

 

實驗分析:

wps49D1.tmp

第二條和第一條就是enter

call f:對應push eip(執行這個動做時候eip實際指向的下一條地址)和mov f地址到eip

wps49E1.tmp

能夠看到指向了23位置

執行f:10行代碼之後:

wps49E2.tmp

12條是把8賦值給eax,eax = 8

13條把8放到了標號5的位置

call g :push eip(此時eip應該是15行代碼位置);

wps49E3.tmp

執行第三行後:

wps49F4.tmp

pop ebp實際就是把ebp 4 內容放回ebp,效果就是ebp又指向原來4的位置,

一樣esp要減4又指向6號標號位置

ret--- pop eip:esp指向標號5位置同時eip指向了15(call下一條指令)

最後leave。esp和ebp都指向4

wps49F5.tmp

wps49F6.tmp

pop後esp+4指向3位置

wps49F7.tmp

最後ret。

wps49F8.tmp

eip指向了23,

addl:eax是默認返回值,eax = 12

leave:最後都指向1,再pop ebp,則均指向0

wps49F9.tmp

有兩點須要注意的地方:

1 函數調用之因此把8放到下一個棧幀ebp+8的位置是由於參數位置是緊跟下一個方法調用棧幀位置,例如當前ebp和esp之間空出了2個位置,那麼8參數要放到靠下緊貼下一個方法調用棧幀位置

2 另外eax是調用者保存寄存器caller save,因此過程當中不須要去管eax

 

 

四、實驗總結–對計算機如何工做的理解
1.計算機的基本原理是存儲程序和程序控制,預先要把指揮計算機如何進行操做的指令序列(稱爲程序)和原始數據經過輸入設備輸送到計算機內存貯器中。每一條指令中明確規定了計算機從哪一個地址取數,進行什麼操做,而後送到什麼地址去等步驟。
計算機在運行時,先從內存中取出第一條指令,經過控制器的譯碼,按指令的要求,從存儲器中取出數據進行指定的運算和邏輯操做等加工,而後再按地址把結果送到內存中去。接下來,再取出第二條指令,在控制器的指揮下完成規定操做。依此進行下去。直至遇到中止指令。簡單來講就是CPU負責處理和運算,存儲器負責保存指令和數據。經過操做系統得調度和安排,不停地進行取址、譯碼、執行的循環。
2.彙編代碼是什麼?
計算機語言的發展過程從機器語言(計算機能直接識別的二進制0和1的組合)->彙編語言(爲了減輕使用機器語言編程的痛苦,人們進行了一種有益的改進:用一些簡潔的英文字母、符號串來替代一個特定的指令的二進制串,依賴於硬件)->高級語言(接近於數學語言或人的天然語言,同時又不依賴於計算機硬件,編出的程序能在全部機器上通用)。
咱們編寫了一個小程序,好比上面實驗中寫到的main.c文件,編譯器執行的過程,這裏寫圖片描述可執行的二進制文件是計算機「認識」的文件,能夠直接執行。 3.以上即是我對此次實驗的總結,計算機很「單純」,它能夠執行不少複雜的指令,但它也是被「告訴」要執行什麼,纔會去執行什麼,經過對彙編語言的分析能夠方便咱們理解計算機處理的過程,瞭解計算機如何工做等等。感謝爲咱們辛苦準備課程的老師!

相關文章
相關標籤/搜索