本文主要从x86汇编一级来查看函数调用和函数指针调用函数的差别。
具体看如下的两个函数:
void show()
{
printf("success\n");
}
void showData(int a)
{
printf("success data a = %d\n", a);
}
下面是两者汇编代码对比:
18: show();
00411AAE E8 3D F6 FF FF call show (4110F0h)
19:
20: void (*ptrShow)() = show;
00411AB3 C7 45 F8 F0 10 41 00 mov dword ptr [ptrShow],offset show (4110F0h)
21: ptrShow();
00411ABA 8B F4 mov esi,esp
00411ABC FF 55 F8 call dword ptr [ptrShow]
00411ABF 3B F4 cmp esi,esp
00411AC1 E8 84 F6 FF FF call @ILT+325(__RTC_CheckEsp) (41114Ah)
22:
23: showData(3);
00411AC6 6A 03 push 3
00411AC8 E8 0E F7 FF FF call showData (4111DBh)
00411ACD 83 C4 04 add esp,4
25: void (*ptrShowData)(int a) = showData;
00411AD0 C7 45 EC DB 11 41 00 mov dword ptr [ptrShowData],offset showData (4111DBh)
26: ptrShowData(3);
00411AD7 8B F4 mov esi,esp
00411AD9 6A 03 push 3
00411ADB FF 55 EC call dword ptr [ptrShowData]
00411ADE 83 C4 04 add esp,4
00411AE1 3B F4 cmp esi,esp
00411AE3 E8 62 F6 FF FF call @ILT+325(__RTC_CheckEsp) (41114Ah)
对比发现,采用函数指针的调用,采用间接调用的过程,即函数的地址首先存到一个变量中,再通过这个变量实现对函数的调用。