示例一:
先看一个 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