2018-2019-1 20189206 《Linux核心原理與分析》第二週作業
阿新 • • 發佈:2018-10-31
Linux核心分析 第二週學習
知識總結
作業系統與核心
- 作業系統 指在整個系統中負責完成最基本功能和系統管理的那些部分
- 核心 實際是作業系統的內在核心
- 核心獨立於普通應用程式,擁有受保護的記憶體空間和訪問硬體裝置的所有許可權,這種空間被稱為核心空間
- 當核心執行的時候,系統以核心狀態進入核心空間執行
- 當應用程式通過系統呼叫與核心通訊時,我們稱核心正在代其執行
- 應用程式稱為通過系統呼叫在核心空間執行,核心被稱為運行於程序上下文中
- 實際上,應用程式通常呼叫庫函式,然後庫函式通過系統呼叫介面,讓核心完成不同任務
- linux是一個單核心,但擁有模組化設計、搶佔式核心、支援核心執行緒及動態裝載核心模組的能力
計算機工作原理
馮諾依曼體系結構
根據馮諾依曼提出的理論:把程式本身當作資料來對待,程式和資料處理用同樣的方式
- CPU 是計算機硬體的基礎,與記憶體和I/O裝置進行互動,其中PC程式暫存器總是指向下一條要執行的命令
- API 程式與計算機的介面
ABI 程式與CPU的介面
x86-32彙編基礎
CPU的暫存器
8086CPU中一共有14個16位暫存器,分別為:
- 資料暫存器
- AX 累加暫存器
- BX 基地址暫存器
- CX 計數器暫存器
- DX 資料暫存器
- 指標暫存器
- SP 堆疊指標暫存器
- BP 基指標暫存器
- 變址暫存器
- SI 源變址暫存器
- DI 目的變址暫存器
- 控制暫存器
- IP 指令指標暫存器
- FLAG 標誌暫存器
- 段暫存器
- CS 程式碼段暫存器
- DS 資料段暫存器
- SS 堆疊段暫存器
- ES 附加段暫存器
【注】在32位CPU中,32位暫存器EAX EBX ECX EDX 不僅可以傳送資料、暫存資料儲存算數羅運算結果,還可以作為指標暫存器。
在定位一個指令時,使用CS:EIP來指明它的地址
定址方式和常用匯編指令
- 運算元
- 立即數 即常數,用$後跟一個數值表示
- 暫存器數 表示某個暫存器儲存的值 用%eax表示
- 儲存器引用 根據計算出來的有效地址,訪問儲存器的某個位置
- 常見彙編指令
- 暫存器定址 操作暫存器而不和記憶體打交道
movl %eax,%edx
表示將暫存器eax中的內容放到ebx中
- 立即定址
movl $0x123, %eax
表示將0x123這個16進位制數放入eax這個暫存器中
- 直接定址
movl 0x123,%edx
表示將0x123記憶體地址所指向的那塊記憶體裡儲存的資料放到EDX暫存器中
- 間接定址
movl (%ebx),%edx
表示取ebx暫存器中儲存的地址的值,放入edx中
- 變址定址
movl 4(%ebx),%edx
表示在間接定址的基礎上,在原地址上加上一個立即數4
- 出棧入棧
pushl %eax
- 相當於
subl $4,%esp movl %eax,(%esp)
將棧頂指標向下移動一位,再將eax的內容放入esp指向的記憶體中 - 由於堆疊是向下增長的,所以用減指令棧頂指標向下移動
- 相當於
popl %eax
- 相當於
movl (%esp),%eax addl $4,%esp
將棧頂數值放在eax暫存器中,esp指標向上移動,棧在收縮
- 相當於
- 函式呼叫
call 0x12345
- 相當於
pushl %eip(*) movl $0x12345, %eip(*)
將當前eip(指向下一條要執行的指令地址)入棧,然後將新的地址賦給eip - 由於不能直接對eip進行操作,所以以上的等價操作都是偽指令
- 相當於
- 函式返回
ret
- 相當於
popl %eip(*)
就是把當前堆疊棧頂的一個儲存單元放到eip暫存器中
- 相當於
- 巨集指令
leave
用來撤銷函式堆疊- 相當於
movl %esp,%ebp popl %ebp
- 相當於
enter
用來建立函式堆疊相當於
pushl %ebp movl %esp,%ebp
- 暫存器定址 操作暫存器而不和記憶體打交道
實驗部分
實驗一 反彙編一個簡單的C程式
通過linux系統的gcc編譯命令的引數-S 編譯出彙編程式main.s 利用vim檢視其中的程式碼。
其中,產生的彙編程式碼中所有以.開頭的命令都是用於連結的輔助資訊,為了檢視到純彙編程式,我們可以將所有帶點的命令刪除,得到的就是彙編程式碼。
對彙編程式碼的分析
- pushl %ebp ebp指標指向棧底,將ebp指向的位置入棧,棧頂指標esp向下移動
- movl %esp , %ebp ebp和esp指向同一個位置
上面兩條命令相當於建立main函式自己的函式呼叫空間 - subl $4,%esp esp指標減4 表示指標向下移動一個位置
- movl $2,(%esp) 將立即數2存入esp指向的位置
- call f 相當於 pushl %eip
movl f,%eip 實際上就是將eip指標指向的程式碼地址入棧,之後將eip指標指向f函式,實現了函式的跳轉
之後再跳轉執行f函式的程式碼。
【注】EAX暫存器是預設儲存函式返回值的暫存器
所有函式的頭兩行指令用於初始化函式自己的函式呼叫堆疊空間
對應的堆疊變化
遇到的問題
- movl %eax,%ebx 是將eax暫存器中儲存的內容給了ebx
movl %esp,%ebp 是將ebp指標指向和esp指標指向的同一個位置
我剛開始就對這兩條命令不是很清楚,為什麼第一條就可以是儲存內容,而第二條就是改變了指標的指向。後來我反應過來,esp和ebp這兩個暫存器儲存的是地址,是堆疊的棧底和棧頂的位置,從實質來看,改變的仍舊是暫存器中的內容。
2.剛開始的堆疊總是畫不對,後來發現是概念錯誤
pushl %esp 首先將esp指標向下移動一位,再將esp指向的地址入棧。