網(wǎng)易云課堂《Linux內(nèi)核分析》作業(yè)
實驗目的:
通過反匯編一個簡單的C程序,分析匯編代碼理解計算機是如何工作的
實驗過程:
登陸實驗樓虛擬機http://www.shiyanlou.com/courses/195
準備main.c源碼
打開終端shell苞氮,輸入以下命令:
gcc –S –o main.s main.c -m32
生成匯編代碼main.s
精簡后的匯編代碼
實驗分析:
先看C語言代碼亡驰,該程序由3個函數(shù)組成泼疑,分別是main()导而、f()献雅、g()谤绳,實現(xiàn)了2+7+5的簡單數(shù)學計算占锯。
程序首先從main()開始,將數(shù)字2傳入f()缩筛,f()又將main()傳入的數(shù)字2原封不動的傳給g()消略,g()實現(xiàn)了將傳入2加5的操作,結(jié)果7返回給f()瞎抛,f()獲得7后直接返回給main()艺演,mian()將獲得的7加7后返回最終結(jié)果14.
理論上編譯后的匯編語言也應該實現(xiàn)上述功能,即計算2+5+7值桐臊。
下面我們來分析精簡后的匯編代碼:
左邊代碼行標表示eip胎撤,紅框表示當前運行的代碼,eax初始化為未知變量断凶,右邊藍色格子表示內(nèi)存段伤提,為簡化描述在32位環(huán)境下1個內(nèi)存單元格表示4byte,ebp和esp初始值均為0
程序從main開始
將ebp壓棧认烁,相當于執(zhí)行以下兩條語句:
subl $4, %esp //esp減4byte肿男,向下移動1格,此時esp指向1
movl %ebp, (%esp) //將ebp的值存入esp指向的存儲單元內(nèi)
將esp的值賦值給ebp却嗡,即ebp也指向1
將esp的值減4舶沛,即esp向下移動1格,此時esp指向2
將數(shù)字2存入esp指向的內(nèi)存塊
調(diào)用f稽穆,相當于執(zhí)行以下兩條語句:
pushl %eip
move f, %eip
call f執(zhí)行完后的狀態(tài)冠王,此時程序完成由main跳轉(zhuǎn)到f
該條指令將ebp-8的位置,即標號為2的內(nèi)存單元所存放的數(shù)字2賦值給eax舌镶,此時eax等于2
跳轉(zhuǎn)到g
將eax的值加5后再存入eax柱彻,此時eax等于7
出棧操作豪娜,相當于以下兩條語句:
movl (%esp), %ebp
addl $4, %esp
ret相當于執(zhí)行以下語句:
popl %eip
leave相當于執(zhí)行以下兩條語句:
movl %ebp, %esp
popl %ebp
g沒有l(wèi)eave指令語句的原因是它沒有再調(diào)用其他函數(shù)
將數(shù)字7累加到eax,此時eax等于14
至此整個程序完成了所有操作哟楷,結(jié)果存放在eax瘤载,即14為最終計算結(jié)果,與C語言代碼一致卖擅。
實驗總結(jié):
計算機有一套規(guī)則來控制程序運行鸣奔,在C語言和匯編語言中,CPU從程序main函數(shù)所在的內(nèi)存地址開始做取指操作惩阶,根據(jù)當前狀態(tài)和輸入計算出新值挎狸,并且進入一個新的狀態(tài),同時改變寄存器所存儲的數(shù)值断楷。
參考:計算機實際上是如何工作的
PS:由于超過了提交作業(yè)時間锨匆,本篇作業(yè)未參與評分
互評作業(yè):
作業(yè)6(該篇作業(yè)未完成,提交了無效鏈接)
作業(yè)10(QZONE)
作業(yè)13(未提供博客鏈接冬筒,僅給出精簡后的匯編代碼)
作業(yè)15(onedrive)
作業(yè)21(未提供博客鏈接恐锣,僅給出C源碼和精簡后的匯編代碼)
作業(yè)22(給個微博鏈接是要互粉嗎?)
作業(yè)24(QZONE)
作業(yè)29(QZONE需要密碼無法查看)
aapu原創(chuàng)作品轉(zhuǎn)載請注明出處《Linux內(nèi)核分析》MOOC課