|
用如下的代码调用成员函数:
CTest test; test.SetValue();
上面的C++代码的汇编代码为:
CTest test; test.SetValue(); 004117DC lea ecx,[test] 004117DF call CTest::SetValue (4111CCh)
同样的,首先把指向对象的指针放到ecx寄存器中;然后调用类CTest的成员函数SetValue()。地址4111CCh那里存放的其实就是一个转跳指令,转跳到成员函数SetValue()内部。
004111CC jmp CTest::SetValue (411750h)
而411750h才是类CTest的成员函数SetValue()的地址。
void CTest::SetValue() { 00411750 push ebp 00411751 mov ebp,esp 00411753 sub esp,0CCh 00411759 push ebx 0041175A push esi 0041175B push edi 0041175C push ecx // 1 0041175D lea edi,[ebp-0CCh] 00411763 mov ecx,33h 00411768 mov eax,0CCCCCCCCh 0041176D rep stos dword ptr es:[edi] 0041176F pop ecx // 2 00411770 mov dword ptr [ebp-8],ecx // 3 m_iValue1 = 13; 00411773 mov eax,dword ptr [this] // 4 00411776 mov dword ptr [eax],0Dh // 5 m_iValue2 = 13; 0041177C mov eax,dword ptr [this] // 6 0041177F mov dword ptr [eax+4],0Dh // 7 } 00411786 pop edi 00411787 pop esi 00411788 pop ebx 00411789 mov esp,ebp 0041178B pop ebp 0041178C ret
下面对上面的汇编代码中的重点行进行分析: 1、将ecx寄存器中的值压栈,也就是把this指针压栈。 2、ecx寄存器出栈,也就是this指针出栈。 3、将ecx的值放到指定的地方,也就是this指针放到[ebp-8]内。 4、取this指针的值放入eax寄存器内。此时,this指针指向test对象,test对象只有两个int型的成员变量,在test对象内存中连续存放,也就是说this指针目前指向m_iValue1。 5、给寄存器eax指向的地址赋值0Dh(十六进制的13)。其实就是给成员变量m_iValue1赋值13。 6、同4。 7、给寄存器eax指向的地址加4的地址赋值。在4中已经说明,eax寄存器内存放的是this指针,而this指针指向连续存放的int型的成员变量m_iValue1。this指针加4(sizeof(int))也就是成员变量m_iValue2的地址。因此这一行就是给成员变量m_iValue2赋值。 通过上面的分析,我们可以从底层了解了C++中this指针的实现方法。虽然不同的编译器会使用不同的处理方法,但是C++编译器必须遵守C++标准,因此对于this指针的实现应该都是差不多的。
共2页: 上一页 [1] 2 下一页
|