文章目錄
- C 函數之間互相調用
- C 程式調用彙程式設計式
- 彙程式設計式調用 C 程式
趙炯;《Linux 核心完全注釋 0.11 修正版 V3.0》Chapte 3.
C 函數之間互相調用
大多數 CPU 上的程式實作使用棧來支援函數調用操作。棧被用來傳遞函數參數、存儲傳回資訊、臨時儲存寄存器原有值以備恢複以及用來存儲局部資料。
單個函數調用操作所使用的棧部分被稱為棧幀結構,在函數執行過程中,棧指針 esp 會随着資料的入棧和出棧而移動,是以函數中對大部分資料的通路都基于幀指針 ebp 進行:
- ebp:幀指針;
- esp;棧指針;
對于函數 A 調用函數 B 的情況,傳遞給 B 的參數包含在 A 的棧幀中,當 A 調用 B 時,函數 A 的傳回位址(調用傳回後繼續執行的指令位址)被壓入棧中,棧中該位置也明确指明了 A 棧幀的結束處。而 B 的棧幀則從随後的棧部分開始。
為了保證某一時刻隻有一個函數在執行,調用者調用其它函數時,被調用者不會修改或覆寫掉調用者今後要使用的寄存器内容,Intel CPU 采用了所有函數必須遵守的寄存器用法:1. 寄存器 eax、edx 和 ecx 的内容必須由調用者自己負責儲存;2. ebx、esi 和 edi 必須由被調用者負責儲存;3. ebp、esp 也需要由被調用者儲存。
void swap(int* a, int* b)
{
int c;
c = *a, *a = *b, *b = c;
}
int main()
{
int a, b;
a = 16; b = 32;
swap(&a, &b);
return a - b;
}
- main 棧幀。儲存局部變量 a 和 b、函數調用的參數 &b 和 &a、傳回位址。
- swap 棧幀。按照慣例,形成棧幀(儲存ebp、esp)、使用 add/sub 取用函數參數、
指令一步退出棧幀。leave
C 語言在調用函數時在堆棧上臨時存放被調函數參數的值。
參數越是最後入棧,越是靠近 C 函數參數左側。
C 程式調用彙程式設計式
從 C 程式中調用彙程式設計式函數的方法與彙程式設計式中調用 C 函數的原理相同,但 Linux 核心程式中不常使用。調用方法的着重點仍然是對函數參數在棧中位置的确定上。如果調用的彙編語言程式比較短,那麼可以直接在 C 程式中使用内聯彙編。
彙程式設計式調用 C 程式
- 彙編中調用 C 函數比較自由,隻要是在棧中适當位置的内容都可以作為參數供 C 函數使用。
- 在調用函數傳回後,彙程式設計式需要再把先前壓入棧中的函數參數清除掉。