天天看點

C 與彙程式設計式的互相調用

文章目錄

  • ​​C 函數之間互相調用​​
  • ​​C 程式調用彙程式設計式​​
  • ​​彙程式設計式調用 C 程式​​
趙炯;《Linux 核心完全注釋 0.11 修正版 V3.0》Chapte 3.

C 函數之間互相調用

大多數 CPU 上的程式實作使用棧來支援函數調用操作。棧被用來傳遞函數參數、存儲傳回資訊、臨時儲存寄存器原有值以備恢複以及用來存儲局部資料。

單個函數調用操作所使用的棧部分被稱為棧幀結構,在函數執行過程中,棧指針 esp 會随着資料的入棧和出棧而移動,是以函數中對大部分資料的通路都基于幀指針 ebp 進行:

  • ebp:幀指針;
  • esp;棧指針;
C 與彙程式設計式的互相調用
對于函數 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 程式中調用彙程式設計式函數的方法與彙程式設計式中調用 C 函數的原理相同,但 Linux 核心程式中不常使用。調用方法的着重點仍然是對函數參數在棧中位置的确定上。如果調用的彙編語言程式比較短,那麼可以直接在 C 程式中使用内聯彙編。

C 與彙程式設計式的互相調用

彙程式設計式調用 C 程式

  • 彙編中調用 C 函數比較自由,隻要是在棧中适當位置的内容都可以作為參數供 C 函數使用。
  • 在調用函數傳回後,彙程式設計式需要再把先前壓入棧中的函數參數清除掉。