函式的呼叫方式分析

2021-07-06 02:00:30 字數 896 閱讀 6065

閒來無事,研究了一下vc中的三種函式呼叫方式 cdcel stdcall fastcall

現將結**布如下:

1 cdcel呼叫方式,呼叫之前的引數壓棧是由呼叫函式完成,函式呼叫結束之後,由呼叫函式彈出堆疊中的引數。但是cdcel的esp指標確是需要由呼叫函式來完成恢復的。

2 stdcall ,呼叫之前的引數壓棧是由呼叫函式來做,子函式來彈出棧中的引數。相當於,呼叫函式push,子函式pop。由子函式恢復esp指標。

3 fastcall ,引數的壓棧和引數的彈出都是由子函式來完成的,相當於 子函式 既負責push 也負責pop,子函式恢復esp指標。

總體上講,cdcel 和fastcall比較正式一點,因為寫程式都講究誰申請誰釋放,而stdcall方式卻將這種成對的操作push和pop在兩個模組中來做,雖然這都是編譯器自動來完成的。但是cdcel的esp指標卻是由呼叫函式來恢復。

另外:這次分析之後的心得就是:程式中的變數如果不是全域性的那麼變數的空間都是分配在棧之上的,這個棧的位址是由sp暫存器指示的,每次函式呼叫,系統都會在esp之後的一定空間(我測試的是esp-40)重新建立棧空間,子函式中的變數就會在這個新的棧上。而且呼叫函式和被呼叫函式的中變數的空間分配位址比較接近,因為每次建立新的棧大概也只有40h這麼個大小的距離,但是全域性變數就不一樣了,我當時測試的全域性變數位址是00424d8c這個位置,而棧區的變數位址是0013ff84附近,還有就是程式的code應該是根據程式的檔案組織結構編譯的,並且由eip進行指示,每次呼叫子函式的時候,當前eip就會被壓棧,子函式結束了就彈出eip,這樣就可以返回到呼叫子函式的地方了。

還不明白的地方是:在新的棧建立的時候,棧底部為什麼要用10h個dword,就是64個位元組來填充一下,還有就是呼叫子函式的時候,先是call一下,但是call的不是子函式的位址,而是跳到乙個位址之後再jmp一下到子函式的位址。

函式呼叫方式

cdecl 是c declaration的縮寫,表示c語言預設的函式呼叫方法 所有引數從右到左依次入棧,這些引數由呼叫者清除,稱為手動清棧。被呼叫函式不需要求呼叫者傳遞多少引數,呼叫者傳遞過多或者過少的引數,甚至完全不同的引數都不會產生編譯階段的錯誤。stdcall 是standard call的縮...

函式呼叫方式

現代的程式語言的函式竟然有那麼多的呼叫方式。這些東西要完全理解還得通過彙編 才好理解。他們各自有自己的特點 其實這些呼叫方式的差別在主要在一下幾個方面 1.引數處理方式 傳遞順序,訪問 利用盞還是暫存器 2.函式的結尾處理方式 善後處理 如 棧的恢復由誰恢復?函式內恢復 還是呼叫後恢復 以下是理論 ...

函式呼叫方式

所謂的呼叫方式是指 在呼叫乙個函式時,約定的傳遞引數方式和平衡堆疊方式,例如 有乙個函式,它有兩個引數 xyz first,second 當我們使用stdcall呼叫方式時,也就是windows呼叫api的常見方式 又幾個函式例外 它的呼叫方式如下 x1 push second x2 push fi...