《Linux內核分析》MOOC課程:在線課程鏈接http://mooc.study.163.com/course/USTC-1000029000
馮諾依曼體系結構的計算機,又叫存儲程序計算機,從硬件的角度來看,其工作模型是CPU依次讀取內存中的指令來完成工作。但它具體是如何完成程序員編寫的非線性執行的程序呢?本次課的實驗,以一段彙編代碼為例,詳細介紹了CPU計算模塊、寄存器和內存是如何配合工作的!
##1 知識準備
###1.1 彙編語言的五種尋址模式
###1.2 幾個重要的彙編指令
Example instruction |
What it does |
Pushl %eax |
Subl $4, %esp //棧頂指針減4,棧在向下生長一個位置 Movl %eax, (%esp) //將eax中的值放入棧頂指針指向的內存位置 |
Popl %eax |
Movl (%esp), %eax //從棧頂指針指向的內存中的值放入eax中 Addl $4, %esp //棧頂指針加4,棧在向上收縮 |
Call 0x12345 |
Pushl %eip //ip壓棧 Movl $0x12345, %eip //將0x12345放入eip中 |
Ret |
Popl %eip //ip出棧 |
##2. 實驗
Ubuntu 12.4 LTS 操作系統,vi 編輯器,gcc 編譯器 2.2 實驗步驟
vi main.c 輸入以下代碼
int g(int x)
{
return x + 3;
}
int f(int x)
{
return g(x);
}
int main(void)
{
return f(8) + 1;
}
保存退出。 在命令行使用下面的命令,將這段c代碼編譯成彙編代碼
gcc –S –o main.s main.c -m32
vi main.s 打開彙編代碼文件,刪除其中以符號點 開頭的語句,得到如下可被計算機執行的彙編代碼:
接下來,就以圖解的方式來分析這段分析代碼。
對照c代碼,很容易就知道,這段彙編代碼也有三個函數,代碼的執行從main函數的第一條語句開始。彙編代碼共有22行可執行的代碼,下面就用22張圖來展示每一條語句執行後,主要寄存器的指向和堆棧的狀態。其中,第0張圖,是程序還未執行時的狀態;第1張圖,是程序執行完第一條語句後的情形;第2張圖,是程序執行完第22條語句後的情形;依次類圖,直到第21張圖。最後一條語句是執行main函數中的 ret 語句,即將跳出了main函數,沒有給出示意圖。
在開始看圖之前,這裡先給出圖示中的一些說明:
好了,上圖: