C語言與匯編語言的相互調用 1 GNU可以把一些變量值放在CPU寄存器中,即所謂寄存器變量, 節省了CPU訪問存儲器的時間。
在嵌入匯編語句中把匯編指令的輸出直接寫到指定的寄存器中,那么此時應該使用局部寄存器變量。
在linux內核中只會使用局部寄存器變量。
在GNU C程序中我們在函數中定義了一個局部寄存器變量如下:
register int res _asm_ ("ax") ;
變量res 希望使用的寄存器是 eax 。 但是變量不一定會存儲在該寄存器中,但是如果該變量用作asm的操作數,
那么還是能夠保證指定的寄存器被用作該操作數。
2
內聯函數 在程序中,一個函數若聲明為Inline,那么就可以讓gcc把函數的代碼集成到調用該函數的代碼中去。
這樣處理就會節省函數調用時進入/退出的時間開銷。
3 C與匯編函數的相互調用
(1) 棧幀結構和控制轉移權方式
CPU使用棧來支持函數調用操作,棧被用來傳遞參數、存儲返回信息、臨時保存寄存器原有值和存儲局部數據。
單個函數調用操作所使用的部分被稱為棧幀結構。
棧幀結構由兩個指針指定,esp為棧指針,ebp為幀指針。

棧是往小的地方擴展,esp指向當前棧頂的元素,通過使用push和pop可以完成數據的出入棧操作。
4 指令CALL 和 指令RET
指令CALL的作用是把返回地址壓入棧中,并且跳轉到被調用函數開始處執行。
返回地址是指的是 緊隨調用CALL后面一條指令的地址,因此當被調函數返回時,就會從該位置繼續執行。
RET指令用于彈出棧頂處的指針并跳到該地址處。在使用該指令之前,首先應該正確處理棧中的內容,使得
當前棧指針所指位置的內容正好是先前CALL指令所保存的返回地址。 另外如果返回值是一個
整數或者是指針的話,
那么寄存器
eax將被默認用來傳遞返回值。
5 在匯編語言中調用C 函數 調用方法如下:
程序需要首先按照逆向的順序把函數參數壓入到堆棧中,即函數的最右邊一個先入棧,
而最左邊的一個參數在最后調用指令之前入棧。
函數調用棧如下:
由上圖可知一旦參數壓棧完畢,則隨之將CALL指令后的一個指令地址壓棧(即Return Address的值)。