标签:
在学习函数指针, 我遇到了问题, 我定义一个指针指向负责打印参数的函数,
1 void (*p)( int ) = Fun;
好奇该指针存放的是什么( 原以为是函数的入口地址),便调试观察一下他们的内存, 这是 函数入口地址 0x00401030 Fun(int), 这是函数指针存放的内容 0x00401005 _Fun。 竟然不一样。
难道说0x00401005是函数名所存放的内存地址?
看来我们在弄懂函数指针前, 需要知道函数名是个什么鬼? )
首先它是个标识符, 其次它是一个 指针, 因为当我试图把 3 赋值给Fun, 编译器告诉我warning C4047: ‘=‘ : ‘void (__cdecl *)(int )‘ differs in levels of indirection from ‘const int ‘。 这是一个函数指针。 看到这我就明白了,函数名标示了一个内存单元,该单元存放了函数的入口地址。 只是这个内存单元不对我们开放,没法赋值的。 否则,编译器报错:error C2106: ‘=‘ : left operand must be l-value。
接下来,我们探讨函数指针是什么鬼?
按理论讲,函数指针指向函数的入口地址。 查看汇编代码, 我在调用Fun处设置个断点, 然后进入这个函数,我发现没有直接进入,如图
@ILT+0(_Fun): 00401005 E9 26 00 00 00 jmp Fun (00401030)
它是跳转到我的Fun函数。 所以,函数指针指向的是跳转命令所在地址。 这不就和书本上的矛盾了。 我又尝试了一下strcmp函数, 这是一个库函数,是否也是这样呢? 于是,我写了一个字符串比较,
1 #include <string.h> 2 #include <stdio.h> 3 4 void 5 main () 6 { 7 int (*p)( const char *, const char * ) = strcmp; 8 char *str1 = "afdf"; 9 char *str2 = "afdf"; 10 11 if ( !p( str1, str2 ) ){ 12 printf( "same\n" ); 13 } 14 }
调试时进入汇编界面, 在If判断语句处设置断点,进入p。我 发现直接进入strcmp函数内,
--- intel\strcmp.asm ---------------------------------------------------------- strcmp: 0040D830 8B 54 24 04 mov edx,dword ptr [esp+4] 0040D834 8B 4C 24 08 mov ecx,dword ptr [esp+8]
奇怪,这跟刚才执行跳转命令不一样。为什么? 这是我自己的想法。 因为库函数已经指定了函数所在的路径, 而用户函数没有。所以需要临时跳转到用户函数的入口地址。
这是我自己的想法,欢迎批评。
标签:
原文地址:http://www.cnblogs.com/the-one/p/4671274.html