C++调用方式 入栈顺序
生活随笔
收集整理的這篇文章主要介紹了
C++调用方式 入栈顺序
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
函數傳參有三種方式:堆棧方式,寄存器方式,以及通過全局變量進行隱含參數的傳遞
1.堆棧方式:
| 約定類型 | __cdecl(C規范) | PASCAL | stdcall | Fastcall |
| 參數傳遞順序 | 從右到左 | 從左到右 | 從右到左 | 使用寄存器和堆棧 |
| 平衡堆棧者 | 調用者 | 子程序 | 子程序 | 子程序 |
| 允許使用VARARG(不定參數) | 是 | 否 | 是 | ? |
?thiscall同樣是參數從右到左,this指針一般放在ecx中,不過不能顯式指定,用于c++的類中
c/c++和MFC程序默認使用調用約定__cdecl
stdcall是Win32 API采用的約定方式,由于函數體本身知道傳進來的參數個數,因此被調用的函數可以在返回前用ret n清理傳送參數的內存棧,
所以test(p1,p2,p3)
| __cdecl調用約定 | PASCAL調用約定 | __stdcall調用約定 |
| push p3 push p2 push p1 call test add esp, 0C//平衡堆棧, 這個是關鍵, 可以在OllyDbg中找到這個 來確定是否為C調用 0C是因為32位環境了, 堆棧操作的對象只能 是雙字操作數(占4個字節) | push p1 push p2 push p3 call test //函數內平衡堆棧 ? | push p3 push p2 push p1 call test//函數內平衡堆棧 |
函數內部調用,如test(p1,p2)
push p2push p1call test{push ebp //保護原有的EBPmov ebp,esp//EBP指向棧頂mov eax,dword ptr [ebp+0c]//調用參數2mov ebx,dword ptr [ebp+08]//調用參數1sub esp,8若函數要用局部變量,則要在堆棧中留出點空間....add esp,8//釋放局部變量所占的堆棧pop ebp//恢復現場ebp指針ret 8,返回ret后的值為參數個數x4h}不理解就畫個圖:
| K | ? | 起始堆棧 |
| k-04h | P2 | EBP+0Ch |
| k-08h | P1 | EBP+08h |
| k-0ch | IP | EBP+04h |
| K-10h | 保存的EBP | EBP |
| k-14h | 局部變量1 | EBP-4h |
| k-18h | 局部變量2 | EBP-8h |
| ESP | 當前ESP指針 | ? |
?
函數返回值一般放在eax寄存器中返回,如果處理結果超過了eax寄存器,其高位就會放在edx寄存器中
總結
以上是生活随笔為你收集整理的C++调用方式 入栈顺序的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 浏览器的兼容性问题
- 下一篇: QT 线程池 + TCP 小试(二)实现