C++中的成员函数调用原理及this指针的传递方式

C++中的成员函数调用原理及this指针的传递方式

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

测试源代码:

1 #include <stdio.h></stdio.h>
2 #include <string.h></string.h>
3
4 classCTestThisPointer
5 {
6 public:
7 CTestThisPointer(intai):mi(ai) { }
8 intAdd(intai)
9 {
10 mi += ai;
11 returnmi;
12 }
13
14 private:
15 intmi;
16 };
17
18
19 intmain()
20 {
21 CTestThisPointer loTest(10);
22
23 printf("%d",loTest.Add(5));
24 return0;
25 }
26

反汇编:

.text:00401000 ; int __cdecl main(int argc, const char **argv, const char *envp)

.text:00401000 _main proc near ; CODE XREF: _mainCRTStartup+AFp

.text:00401000

.text:00401000 this = byte ptr -4

.text:00401000 argc = dword ptr 8

.text:00401000 argv = dword ptr 0Ch

.text:00401000 envp = dword ptr 10h

.text:00401000

.text:00401000 push ebp ; 在默认优化的时候,总算看到了正统的一个push ebp;

.text:00401000 ; mov ebp,esp的保护堆栈并用ebp的过程

.text:00401001 mov ebp, esp

.text:00401003 push ecx

.text:00401004 push 0Ah ; 构造函数的除了默认this外的唯一参数,10

.text:00401006 lea ecx, [ebp+this] ; 这个参数时this指针,通过寄存器ecx传递

.text:00401009 call CTestThisPointer__CTestThisPointer

.text:0040100E push 5 ; Add函数除默认的this外唯一的参数,5

.text:00401010 lea ecx, [ebp+this] ; this指针

.text:00401013 call CTestThisPointer__Add

.text:00401018 push eax ; 将add的返回值入栈,调用printf

.text:00401019 push offset aD ; "%d"

.text:0040101E call _printf

.text:00401023 add esp, 8 ; 变长参数的函数,只能是通过__cdecl调用约定罗,由main

.text:00401023 ; 函数来维护栈平衡

.text:00401026 xor eax, eax

.text:00401028 mov esp, ebp

.text:0040102A pop ebp

.text:0040102B retn

.text:0040102B _main endp

构造函数:

.text:00401030 CTestThisPointer__CTestThisPointer proc near ; CODE XREF: _main+9p

.text:00401030

.text:00401030 var_4 = dword ptr -4

.text:00401030 arg_0 = dword ptr 8

.text:00401030

.text:00401030 push ebp

.text:00401031 mov ebp, esp

.text:00401033 push ecx ; 将this指针入栈保存

.text:00401034 mov [ebp+var_4], ecx

.text:00401037 mov eax, [ebp+var_4] ; 将this的值传给eax,默认优化的代码实在够繁琐,接下来

.text:00401037 ; 几步都是的,其实本质无非就是一个

.text:00401037 ; mov [ecx],[ebp+arg_0]的过程,但是因为不能直接的从

.text:00401037 ; 内存mov到内存,所以中间用了临时变量,但是因为要用

.text:00401037 ; 寄存器做临时变量,所以得先保存寄存器。。。。。

.text:00401037 ; 其实还有那么多寄存器,咋不用呢?呵呵,因为是默认优化

.text:0040103A mov ecx, [ebp+arg_0]

.text:0040103D mov [eax], ecx

.text:0040103F mov eax, [ebp+var_4]

.text:00401042 mov esp, ebp

.text:00401044 pop ebp

.text:00401045 retn 4

.text:00401045 CTestThisPointer__CTestThisPointer endp

Add函数:

.text:00401050 CTestThisPointer__Add proc near ; CODE XREF: _main+13p

.text:00401050

.text:00401050 var_4 = dword ptr -4

.text:00401050 arg_0 = dword ptr 8

.text:00401050

.text:00401050 push ebp

.text:00401051 mov ebp, esp

.text:00401053 push ecx

.text:00401054 mov [ebp+var_4], ecx ; 这个临时变量用的最费

.text:00401057 mov eax, [ebp+var_4]

.text:0040105A mov ecx, [eax]

.text:0040105C add ecx, [ebp+arg_0] ; 因为返回的是mi,所以以下是老老实实的取出this指针中的

.text:0040105C ; 地址到寄存器,然后在通过mov re,[re]的形式取出值

.text:0040105C ; BTW:看没有优化的代码实在不习惯

.text:0040105F mov edx, [ebp+var_4]

.text:00401062 mov [edx], ecx

.text:00401064 mov eax, [ebp+var_4]

.text:00401067 mov eax, [eax]

.text:00401069 mov esp, ebp

.text:0040106B pop ebp

.text:0040106C retn 4

.text:0040106C CTestThisPointer__Add endp

write by 九天雁翎(JTianLing) -- blog.csdn.net/vagrxie

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值