windbg-调试技巧(定长、不定长参数thiscall平衡堆栈方式不同)

本文探讨了C++中thiscall调用约定如何处理成员函数,并解释了遇到可变参数时编译器如何切换到C调用约定。通过实例演示了不同调用约定下栈的清理方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

C++程序的成员函数默认使用的调用约定是thiscall,这种约定是把this指针放到ECX寄存器中.This调用协定也是要求被调用函数负责清理栈,因此不支持可变数时的参数,当我们在C++类中定义了可变数量参数的成员函数时,偏译器会自动改为使用C调用约定,当这种调用时,编译器会将所有参数压入栈中,再将this指针压入栈:

关键两点:1.this时,是被调用函灵敏清理栈 2.如果可变参数,则使用C约定,由调用者来清理

写个小demo测试:

[cpp]  view plain  copy
  1. #include "stdafx.h"  
  2. #include <stdio.h>  
  3. enum MEAL {BREAKFAST, LUNCH, SUPPER};  
  4.   
  5. class Cat  
  6. {  
  7. public:  
  8.     MEAL Fun0(MEAL i)  
  9.     {  
  10.         return i;         
  11.     }  
  12.     char* Fun1(MEAL i, ...)  
  13.     {  
  14.         return 0;  
  15.     }  
  16. };  
  17.   
  18.   
  19. int main(int argc, char* argv[])  
  20. {  
  21.      
  22.     Cat cat;  
  23.     cat.Fun0(BREAKFAST);  
  24.     cat.Fun1(BREAKFAST, "meat""beaf""rice");  
  25.   
  26.     return 0;  
  27. }  

[cpp]  view plain  copy
  1. 0:000> x ThisCall!Cat::*  
  2. 00401060 ThisCall!Cat::Fun0 (MEAL)  
  3. 00401090 ThisCall!Cat::Fun1 (MEAL)  
  4. 0:000> x ThisCall!main  
  5. 00401000 ThisCall!main (intchar **)  
  6. 0:000> bp 00401000   
先在main处下断点:

[cpp]  view plain  copy
  1. ThisCall!main:  
  2. 00401000 55              push    ebp  
  3. 00401001 8bec            mov     ebp,esp  
  4. 00401003 83ec44          sub     esp,44h  
  5. 00401006 53              push    ebx  
  6. 00401007 56              push    esi  
  7. 00401008 57              push    edi  
  8. 00401009 8d7dbc          lea     edi,[ebp-44h]  
  9. 0040100c b911000000      mov     ecx,11h  
  10. 00401011 b8cccccccc      mov     eax,0CCCCCCCCh  
  11. 00401016 f3ab            rep stos dword ptr es:[edi]  
  12. 00401018 6a00            push    0//入值BREAKFAST  
  13. 0040101a 8d4dfc          lea     ecx,[ebp-4]//这地方明显ebp-4为Cat cat这个局部变量,也就是把this赋给ECX  
  14. 0040101d e83e000000      call    ThisCall!Cat::Fun0 (00401060)//Fun0后调用者不用清栈  
  15. 00401022 68fce04000      push    offset ThisCall!`string' (0040e0fc)  
  16. 00401027 68f4e04000      push    offset ThisCall!`string' (0040e0f4)  
  17. 0040102c 68ece04000      push    offset ThisCall!`string' (0040e0ec)  
  18. 00401031 6a00            push    0  
  19. 00401033 8d45fc          lea     eax,[ebp-4]  
  20. 00401036 50              push    eax  
  21. 00401037 e854000000      call    ThisCall!Cat::Fun1 (00401090)  
  22. 0040103c 83c414          add     esp,14h//Fun1后调用者需要清栈  
这样就看得很清楚了.
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值