C++ 的 return 实现了什么 ? 汇编查看

示例一:

先看一个 int 的返回;

C++ 实现:

int get_int()
{
    int nTemp = 123;

    return nTemp;
}

void CtmfcDlg::OnBnClickedButton()
{
    int n1 = get_int();

    n1 = 0;

}
 

汇编:

int get_int()  //第二步;
{
000E2690  push        ebp  
000E2691  mov         ebp,esp  
000E2693  sub         esp,0CCh  
000E2699  push        ebx  
000E269A  push        esi  
000E269B  push        edi  
000E269C  lea         edi,[ebp-0CCh]  
000E26A2  mov         ecx,33h  
000E26A7  mov         eax,0CCCCCCCCh  
000E26AC  rep stos    dword ptr es:[edi]  

    int nTemp = 123;
000E26AE  mov         dword ptr [nTemp],7Bh   //赋值;7BH(16进制) == 123(10进制);

    return nTemp;
000E26B5  mov         eax,dword ptr [nTemp]  //嗯,就是这里,nTemp 赋值 eax;
}
000E26B8  pop         edi  
000E26B9  pop         esi  
000E26BA  pop         ebx  
000E26BB  mov         esp,ebp  
000E26BD  pop         ebp  
000E26BE  ret  


void CtmfcDlg::OnBnClickedButton2()  //第一步
{
000E26C0  push        ebp  
000E26C1  mov         ebp,esp  
000E26C3  sub         esp,0D8h  
000E26C9  push        ebx  
000E26CA  push        esi  
000E26CB  push        edi  
000E26CC  push        ecx  
000E26CD  lea         edi,[ebp-0D8h]  
000E26D3  mov         ecx,36h  
000E26D8  mov         eax,0CCCCCCCCh  
000E26DD  rep stos    dword ptr es:[edi]  
000E26DF  pop         ecx  
000E26E0  mov         dword ptr [ebp-8],ecx  
    // TODO: 在此添加控件通知处理程序代码

    int n1 = get_int();
000E26E3  call        get_int (0E18E3h)          //调用 get_int() ;
000E26E8  mov         dword ptr [n1],eax     //将 eax 的内容放到 n1 中;  eax 是寄存器; 看一下 eax 内容是什么,看第二步;


    n1 = 0;
000E26EB  mov         dword ptr [n1],0  

}

 

很简单,很清楚了;

 

 

 

 

 

 

示例二:

返回一个 class;

 

C++ 源码:

class CTest
{
public:
    CTest()
    {
        m_n = 1;
    }

    ~CTest()
    {
        m_n = 0;
    }
    
    int m_n;

    void set_n(int n)
    {
        m_n = n;
    }
};


CTest get_test2()
{
    CTest test2;

    return test2;
}

void CtmfcDlg::OnBnClickedButton1()
{
    // TODO: 在此添加控件通知处理程序代码
 
    CTest t2 = get_test2();

    int nTemp = 123;    
}

 

汇编:

只看重点:

 

CTest get_test2()
{
00B67EC0  push        ebp  
00B67EC1  mov         ebp,esp  
00B67EC3  push        0FFFFFFFFh  
00B67EC5  push        offset __ehhandler$?get_test2@@YA?AVCTest@@XZ (0B68CAFh)  
00B67ECA  mov         eax,dword ptr fs:[00000000h]  
00B67ED0  push        eax  
00B67ED1  sub         esp,0D8h  
00B67ED7  push        ebx  
00B67ED8  push        esi  
00B67ED9  push        edi  
00B67EDA  lea         edi,[ebp-0E4h]  
00B67EE0  mov         ecx,36h  
00B67EE5  mov         eax,0CCCCCCCCh  
00B67EEA  rep stos    dword ptr es:[edi]  
00B67EEC  mov         eax,dword ptr [___security_cookie (0B70184h)]  
00B67EF1  xor         eax,ebp  
00B67EF3  push        eax  
00B67EF4  lea         eax,[ebp-0Ch]  
00B67EF7  mov         dword ptr fs:[00000000h],eax  
00B67EFD  mov         dword ptr [ebp-0E0h],0  
    CTest test2;
00B67F07  lea         ecx,[ebp-14h]                       // ebp-14h 就是 test2 的地址; &test2 == ebp-14h ;ecx 保存 test2 地址;
00B67F0A  call        CTest::CTest (0B618C0h)  //构造函数;汇编部分保存 this 指针;

    return test2;
00B67F0F  mov         eax,dword ptr [ebp+8]  
00B67F12  mov         ecx,dword ptr [ebp-14h]  // ecx 获取 test2 内存内容;
00B67F15  mov         dword ptr [eax],ecx         //ecx 赋值 eax; 
00B67F17  mov         dword ptr [ebp-4],0       
00B67F1E  mov         edx,dword ptr [ebp-0E0h]  
00B67F24  or          edx,1  
00B67F27  mov         dword ptr [ebp-0E0h],edx  
00B67F2D  lea         ecx,[ebp-14h]  
00B67F30  call        CTest::~CTest (0B61023h)  // 析构函数,这里;
00B67F35  mov         eax,dword ptr [ebp+8]   //赋值 eax , ebp+8:查看推荐的文章;

}

 

from:https://blog.csdn.net/jimoguilai/article/details/28426999

EBP+C: second parameter
EBP+8: first parameter
EBP+4: return address
EBP:   previous EBP
EBP-4: local variable
EBP-8: local variable

 

 

void CtmfcDlg::OnBnClickedButton1()
{
00B635E0  push        ebp  
00B635E1  mov         ebp,esp  
00B635E3  sub         esp,0E4h  
00B635E9  push        ebx  
00B635EA  push        esi  
00B635EB  push        edi  
00B635EC  push        ecx  
00B635ED  lea         edi,[ebp-0E4h]  
00B635F3  mov         ecx,39h  
00B635F8  mov         eax,0CCCCCCCCh  
00B635FD  rep stos    dword ptr es:[edi]  
00B635FF  pop         ecx  
00B63600  mov         dword ptr [ebp-8],ecx  
    // TODO: 在此添加控件通知处理程序代码
 
    CTest t2 = get_test2();
00B63603  lea         eax,[t2]                           //获取 t2 的地址,赋值到 eax 中;
00B63606  push        eax               
00B63607  call        get_test2 (0B6179Eh)  //
00B6360C  add         esp,4  

    int nTemp = 123;    
00B6360F  mov         dword ptr [nTemp],7Bh  
}

 

简单解析:

eax 保存 左值变量  地址,然后调用 返回值函数 get_test2(),在get_test2()  函数中将 临时变量赋值到 eax 中;

在 赋值之前,执行了析构函数;

 

推荐一篇详细的文章:

《C/C++ return 如何实现的?return 的内部机制》

https://blog.csdn.net/jmh1996/article/details/78384083

 

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

chinabinlang

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值