鄭卓彬 + 原創(chuàng)作品轉(zhuǎn)載請注明出處 + 《Linux內(nèi)核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000
前言:
? ? 第一節(jié)課,老師講了馮諾依曼計算機的程序執(zhí)行流程,以及部分匯編指令,和匯編代碼中的函數(shù)棧。
計算機程序運行:
? ? 馮諾依曼計算機,分為運算器、控制器、存儲器、輸入設(shè)備、輸出設(shè)備五部分。其中運算器、控制器就是計算機中的cpu,cpu中有寄存器、程序計數(shù)器。當程序在計算機中運行時,cpu中的ip寄存器存儲著下一條指令的地址,每當一條指令執(zhí)行完,cpu就從ip寄存器中取出相應(yīng)指令的地址進行解析執(zhí)行,并且ip自動加一指向下一條需要執(zhí)行指令的地址。
匯編基礎(chǔ):
? ? 匯編語言是較為底層的語言,也是計算機指令與高級語言的接口,本章學習了基礎(chǔ)的匯編命令和8086cpu的各個寄存器作用。
寄存器作用:

匯編指令:

解析: ?mov指令,用于將 源 里的數(shù)據(jù)傳到 目的 ?其中該指令的源在 后面跟著的左半部分,目的在右半部分。 但是根據(jù)尋址模式的不同,會傳回不同的參數(shù),如寄存器模式就是將前一個寄存器中的值傳入后一個寄存器,立即數(shù)尋址就是將該數(shù)字傳到目的等。

解析: ?如圖,左邊的一條指令就相當與右邊的多條指令。
實驗例子:
對于如下的c代碼 ? :

可用 gcc ?解析為中間文件,并將,將中間文件中的帶.開頭的句子刪除,就剩下這c程序?qū)?yīng)的匯編代碼了:
對應(yīng)匯編代碼:

匯編代碼如上,各個分段對應(yīng)圖四的函數(shù)。
匯編代碼基礎(chǔ):
1、每個函數(shù)的調(diào)用都會在該程序的棧中添加一個函數(shù)棧區(qū),用來保存該函數(shù)的上下文。
2、ebp和esp寄存器:ebp寄存器指向該函數(shù)棧的棧底,且棧底的內(nèi)容存儲的是上一個棧底的地址。esp的內(nèi)容是棧頂?shù)牡刂贰?/p>
匯編代碼解析:
1、main函數(shù):
? ? pushl %ebp ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ??
? ? movl%esp, %ebp ? ? ? ? ? #以上兩條語句,將的ebp中的內(nèi)容存到棧中做棧底,并把ebp重新指向該棧底
? ? subl$4,%esp
? ? movl$2,(%esp) ? ? ? ? ? ? ? ?#以上兩條語句將數(shù)2壓棧
? ? call f ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#調(diào)用f函數(shù),是將eip中的值壓棧(函數(shù)調(diào)用回來后要執(zhí)行的指令),并將f函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 的地址存入eip
? ? addl$3,%eax ? ? ? ? ? ? ? ? ? ?#將傳回的數(shù)與立即數(shù)3相加
? ? leave ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#將棧頂?shù)刂纷優(yōu)闂5椎刂?,也就是使該棧成為空棧,并將ebp寄存器中的值改 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?為上個棧底
? ? ret ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?#結(jié)束
2、f函數(shù):
? ? pushl %ebp
? ? movl%esp, %ebp ? ? ? ? #以上兩條語句,將的ebp中的內(nèi)容存到棧中做棧底,并把ebp重新指向該棧底
? ? subl$4,%esp
? ? movl8(%ebp), %eax ? ?
? ? movl%eax, (%esp)? ? ? #以上三條語句將main函數(shù)中壓棧的值2給取到eax寄存器中,并且將該值也壓到f ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 函數(shù)的棧中
? ? call g? ? ? ? ? ? ? ? ? ? ? ? ? ? #調(diào)用g函數(shù),是將eip中的值壓棧(函數(shù)調(diào)用回來后要執(zhí)行的指令),并將f函數(shù) ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 的地址存入eip
? ? leave ? ? ? ? ? ? ? ? ? ? ? ? ? ?#將棧頂?shù)刂纷優(yōu)闂5椎刂?,也就是使該棧成為空棧,并將ebp寄存器中的值改? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? 為上個棧底
? ? ret? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? #將main函數(shù)壓棧的eip值返回到eip寄存器中,既繼續(xù)執(zhí)行調(diào)用main函數(shù)的下面一 ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ? ?條指令
3、g函數(shù):
? ? pushl %ebp
? ? movl%esp, %ebp ? ? #以上兩條語句,將的ebp中的內(nèi)容存到棧中做棧底,并把ebp重新指向該棧底
? ? movl8(%ebp), %eax
? ? addl$1,%eax? ? ? ? ? ? #以上兩條語句將f函數(shù)中壓棧的值2給取到eax寄存器中,并且加一,用于返回
? ? popl %ebp ? ? ? ? ? ? ? ?#彈出f函數(shù)的棧底到ebp中
? ? ret? ? ? ? ? ? ? ? ? ? ? ? ? ? #將f函數(shù)壓棧的eip值返回到eip寄存器中,既繼續(xù)執(zhí)行調(diào)用f函數(shù)的下面一條指令
總結(jié):
? ? 我理解的計算機其實是很笨的,一直的動作就是取指令,運行,取指令,運行。計算機之所以能體現(xiàn)的較為智能,是程序員一步步迭代的過程,程序員將顯示生活中存在的實物或者抽象和邏輯用高級語言編寫出來。所以計算機其實是人的思想的體現(xiàn),只是他能之分認真的執(zhí)行工作,可以24小時執(zhí)行且基本不出錯。
真實姓名(與最后申請證書的姓名務(wù)必一致) + 原創(chuàng)作品轉(zhuǎn)載請注明出處 + 《Linux內(nèi)核分析》MOOC課程http://mooc.study.163.com/course/USTC-1000029000