原理
#pragma once
void
func1()
;__declspec
(dllimport)
void
func2()
;
#include
"dll.h"
#pragma comment(lib,"../debug/dll.lib")
intmain()
011f16ae e8 cefaffff call 011f1181
011f16b3 8bf4 mov esi, esp
011f16b5 ff15 00901f01 call dword ptr [<&dll.#2>] ; dll.func2
011f1181 /e9 58050000 jmp func1 ; jmp 到 offset dll.func1
011f1186 |e9 59050000 jmp func2 ; jmp 到 offset dll.func2
offset dll.func1:
011f16de >- ff25 04901f01 jmp dword ptr [<&dll.func1>] ; dll.func1
011f16e4 >- ff25 00901f01 jmp dword ptr [<&dll.#2>] ; dll.func2
dll.func1:
0fe41140 > /e9 1b0a0000 jmp func1
0fe41145 > |e9 66120000 jmp func2
func1:
0fe41b60 > 55 push ebp
0fe41b61 8bec mov ebp, esp
...
011f16ae e8 cefaffff call 011f1181
011f16b3 8bf4 mov esi, esp
011f16b5 ff15 00901f01 call dword ptr [<&dll.#2>] ; dll.func2
0fe41140 > /e9 1b0a0000 jmp func1
0fe41145 > |e9 66120000 jmp func2
func2沒有跳轉到offset dll.func1,而是直接跳轉到dll.func2。
輸入函式有高效和低效兩種呼叫情況。
預設對輸入api使用低效形式。
由於使用了額外的jmp,所以執行時間長一些。
要想優化,可以在宣告處加上__declspec(dllimport)
,告訴編譯器這個函式來自dll。所以主函式的func2是這樣的:
011f16b5 ff15 00901f01 call dword ptr [<&dll.#2>] ; dll.func2
這種jmp有點像c++的虛函式表。
呼叫函式和被呼叫函式的關係
1 當在乙個函式的執行期間呼叫另乙個函式時,在執行被呼叫函式之前,系統需要完成三件事情 1 將所有的實參 返回位址等資訊傳遞給被呼叫函式儲存 2 為被呼叫函式的區域性變數分配儲存區 3 將控制轉移到被調函式的入口。2 從被呼叫函式返回到呼叫函式之前,系統要做三件事情 1 儲存被調函式的計算結果 2 ...
函式的引數和函式呼叫
1 函式的引數 在呼叫函式時,大多數情況下主調函式和被調函式之間存在著資料傳遞關係。於是就用到了形式引數和實際引數,簡稱形參和實參。在定義函式時函式名後面括號中的變數稱為 形參 在主調函式 一般為main 呼叫乙個函式時,函式名後面括號中的引數 可以是乙個表示式 稱為 實參 例如 void func...
系統呼叫和函式呼叫的區別
作業系統服務的程式設計介面 通常由高階語言編寫 c或c 程式訪問通常通過高層次 的api介面 c標準庫的庫函式 而不是直接進行系統呼叫 每個系統呼叫對應乙個系統呼叫編號 系統呼叫 1.使用int和iret指令,核心和應用程式使用的是不同的堆疊,因此存在堆疊的切換,從使用者態切換到核心態,從而可以使用...