调用成员函数与普通函数的差别在于,调用成员函数时要先转到跳转表,再到函数入口。
Test.SetNumber(5);
00407797 6A 05 push 5
00407799 8D 45 F8 lea eax,[Test]
0040779C 50 push eax
0040779D E8 79 C8 FF FF call CTest::SetNumber (040401Bh)
jmp表
___vcrt_GetModuleHandleW:
00404002 E9 A9 84 00 00 jmp __vcrt_GetModuleHandleW (040C4B0h)
__crt_stdio_output::output_processor<char,__crt_stdio_output::stream_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::stream_output_adapter<char> > >::type_case_s_compute_narrow_string_length:
00404007 E9 74 3E 04 00 jmp __crt_stdio_output::output_processor<char,__crt_stdio_output::stream_output_adapter<char>,__crt_stdio_output::standard_base<char,__crt_stdio_output::stream_output_adapter<char> > >::type_case_s_compute_narrow_string_length (0447E80h)
__crt_interlocked_compare_exchange_pointer<void __cdecl(void),std::nullptr_t,std::nullptr_t>:
0040400C E9 5F 9E 01 00 jmp __crt_interlocked_compare_exchange_pointer<void __cdecl(void),std::nullptr_t,std::nullptr_t> (041DE70h)
__atol_l:
00404011 E9 6A DA 05 00 jmp _atol_l (0461A80h)
__vcrt_va_start_verify_argument_type<char const * const>:
00404016 E9 75 38 00 00 jmp __vcrt_va_start_verify_argument_type<char const * const>+10h (0407890h)
CTest::SetNumber:
0040401B E9 40 38 00 00 jmp CTest::SetNumber (0407860h)
00404020 CC int 3
00404021 CC int 3
00404022 CC int 3
class CTest
{
public:
void __stdcall SetNumber(int nNumber)
{
00407860 55 push ebp
00407861 8B EC mov ebp,esp
m_nInt = nNumber;
00407863 8B 45 08 mov eax,dword ptr [this]
00407866 8B 4D 0C mov ecx,dword ptr [nNumber]
00407869 89 08 mov dword ptr [eax],ecx
}
0040786B 5D pop ebp
0040786C C2 08 00 ret 8