c/c++中的函数指针怎样工作(未完成)

阅读更多
void fn(){};                      5:   55                      push   %ebp             
int main(){                       6:   89 e5                   mov    %esp,%ebp            
    void (*pf)(void)=&fn;         8:   83 e4 f0                and    $0xfffffff0,%esp 
    (*pf)();                      b:   83 ec 10                sub    $0x10,%esp       
}                                 e:   e8 00 00 00 00          call   13 <_main+0xe>   
                                 13:   c7 44 24 0c 00 00 00    movl   $0x0,0xc(%esp)   
                                 1a:   00                                              
                                 1b:   8b 44 24 0c             mov    0xc(%esp),%eax   
                                 1f:   ff d0                   call   *%eax            
                                 21:   b8 00 00 00 00          mov    $0x0,%eax        
                                 26:   c9                      leave                   
                                 27:   c3                      ret                     
语句sub $0x10,%esp在栈上分配空间为16个字节,而pf占用了栈底部4字节地址,0xc(%esp)是变量pf在栈上分配的地址。
注意到movl $0x0,0xc(%esp),这里实际就是将函数地址0x0赋予了变量pf,而后pf这个内存变量的内容会被赋予到eax寄存器,函数fn()的代码通过call *%eax被调用,这个调用非常容易理解。
注意下面这个代码也是可以工作的:
void fn(){};
int main(){
    (*fn)();        call   0 <__Z2fnv>
}
注意这里fn()直接使用函数指针的语法进行了调用,编译器产生的汇编没有使用变量,直接按函数地址调用了fn()。

你可能感兴趣的:(c/c++中的函数指针怎样工作(未完成))