最近在学习c++ primer,分析了一下String类构造的时候反汇编代码,做点笔记。
//无参构造
string d;
004013B3 lea eax,[ebp-50h] //不知道有什么用,跟进去貌似也就初始化了一个参数。004013B6 push eax //最后一个参数,c++采用的是stdcall,参数从右到左压栈
004013B7 lea ecx,[ebp-1Ch] //this指针传递,也是就上面的那个变量d,未指明stdcall,cdecl函数调用方式的话,this指针一般通过ecx传递004013BA call @ILT+165(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_str//调用构造函数,传递不同的参数调用不同的构造函数,我们下面几个string构造调用的是不同的构造函数。这个是编译的时候就已经确定好的。由于这里是stdcall方式,所以栈的平衡由被调用方确定;cdecl方式,栈由调用方平衡。
004013BF mov dword ptr [ebp-4],0 //这个变量保存申请堆栈的次数
//字面值构造
string a("abc");
004013C6 lea ecx,[ebp-54h]//不知道有什么用,跟进去貌似也就初始化了一个参数。004013C9 push ecx //最后一个参数,c++采用的是stdcall,参数从右到左压栈
004013CA push offset string "abc" (0043101c)//常量abc存储的地址压栈
004013CF lea ecx,[ebp-2Ch] //this指针传递
004013D2 call @ILT+160(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_str//构造函数
004013D7 mov byte ptr [ebp-4],1//这个变量保存申请堆栈的次数。
由第一个和第二个构造函数的this可以看出,string对象的占用的内存大小是10h。
string b(a);//一直以为这个是指向另外一个变量,后面才发现这里是构造了另外一个对象
004013DB lea edx,[ebp-2Ch]004013DE push edx //最后一个参数,c++采用的是stdcall,参数从右到左压栈,这里是string对象a压栈
004013DF lea ecx,[ebp-3Ch] //this指针传递
004013E2 call @ILT+150(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_str//构造函数
004013E7 mov byte ptr [ebp-4],2//这个变量保存申请堆栈的次数
string c(10,'a');
004013EB lea eax,[ebp-58h]004013EE push eax//最后一个参数,c++采用的是stdcall,参数从右到左压栈,这里是string对象a压栈
004013EF push 61h//倒数第二个参数‘a’的ascii码值
004013F1 push 0Ah//倒数第三个参数10
004013F3 lea ecx,[ebp-4Ch]//this指针
004013F6 call @ILT+50(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::basic_stri//构造函数
最后,出了这个作用域,编译器会自动调用析构函数
lea ecx,[ebp-1Ch]
0040142C call @ILT+105(std::basic_string<char,std::char_traits<char>,std::allocator<char> >::~basic_st
从上面可以看出,this指针都是通过ecx传递,传递不同的参数编译器编译的时候就调用不同的构造函数,每一个string对象占用了10h个字节的内存。构造函数太复杂了,就没有跟进去看。