C++反汇编构造函数篇(二)

  本次实验采用的是g++ 4.7.2的编译器,Kali Linux 32位的操作系统,以及Windows下VC++2013的编译器。

  例子代码保存的文件名为student.cpp:
#include <iostream>
using namespace std;
 
class Student{
private:
    int id;
 
public:
    void setId (int m_id)
    {
         this->id = m_id;
        
    }
    int getId ()
    {
         return this ->id;
    }
 
};
 
int main()
{
    Student t;
    t.setId (10086);
    cout<<t .getId()<< endl;
    return 0;
}
编译:g++  -o stu  student.cpp
反汇编:objdump -d stu
得到的main函数的反汇编代码如下:
  8048785 :   c7 44 24 04 66 27 00     movl   $0×2766 , 0×4(% esp );10086  16进制形式
  804878c :    00
  804878d :    8d 44 24 1c              lea     0x1c (% esp ),%eax ; 取得this 指针
  8048791 :    89 04 24                 mov     %eax ,(%esp ) ;this指针入栈
  8048794 :   e8 99 00 00 00             call    8048832 < _ZN7Student5setIdEi >; 调用setId(int m_id) 函数
  8048799 :    8d 44 24 1c              lea     0x1c (% esp ),%eax
  804879d :    89 04 24                 mov     %eax ,(%esp )
  80487a0 :   e8 9b 00 00 00            call    8048840 < _ZN7Student5getIdEv >; 调用getID() 函数
 
 
  我们的代码中没有定义构造函数,按以往的理解,编译器会提供默认的构造函数。可是咧,从反汇编的代码中我们哪里看得到默认构造函数的影子呢?
另外,我们知道VC++的编译器会使用ecx寄存器传递this指针,没有压入栈中。而观察g++的编译器会发现,其this指针是需要压入栈中的。我们注意观察到函数在调用setId(int m_id)和getID()函数前都需要从栈中取得this指针,并push到栈中。
再来看看同样的代码在VC++2013中debug模式下的汇编代码是咋样的?
    Student t ;
    t.setId (10086 ) ;
00C45428   push        2766h  
00C4542D   lea         ecx ,[t ]  
00C45430   call        Student :: setId ( 0C410F0h ) 
    cout << t.getId () << endl ;
00C45435   mov         esi , esp 
00C45437   push        0C4139Dh  
00C4543C   lea         ecx ,[t ]  
00C4543F   call        Student :: getId ( 0C411F4h ) 
也是可以看出的,没有调用默认的构造函数。至于什么时候需要调用默认的构造函数,将于在虚函数的那个章节进行分析。