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语言的不同,被extern "C"修饰的变 量和函数是按照C语言方式编译和连接的。由于编译后的名字不同,C++程序不能直接调 用C 函数。C++提供了一个C 连接交换指定符号...
请根据给定的main函数及程序输出,完成设计。具体要求如下。 一、请设计一个Book类(与动态数组类的要求一致): 1、包括私有成员: unsigned int m_ID;//编号 string m_Name;//书名 string m_Introductio//简介 ...
而32位的系统中每一运行的程序都会有一个消息队列,所以系统可以在多个消息队列中转换而不必等待当前程序完成消息处理就可以得到控制权。这种多任务系统就称为抢先式的多任务系统。Windows95/NT就是这种系统。 1.3 ...
IvorHorton还著有关于C、C++和Java的多部入门级好书,如《C语言入门经典(第4版)》和《C++入门经典(第3版)》。 译者 杨浩,知名译者,大学讲师,从事机械和计算机方面的教学和研究多年,发表论文数篇,参编和翻译的...
//这三个函数中记录的 //判断此时触点时否己连接非常重要 if(IsPutLinked()) { //如果此时触点己连接,则退出 return; } //此时鼠标移进触点 //当前是连接态吗? if...
1.36 我总算弄清楚函数指针的声明方法了,但怎样才能初始化呢? 20 1.37 能够初始化联合吗? 20 第2章 结构、联合和枚举 21 结构声明 21 2.1 struct x1{ };和typedef struct{ }x2; 有什么不同? 21 2.2...
请根据给定的main函数及程序输出,完成设计。具体要求如下。 一、请设计一个Book类: 1、包括私有成员: unsigned int m_ID;//编号 string m_Name;//书名 string m_Introductio//简介 string m_Author;//作者 ...
1.36 我总算弄清楚函数指针的声明方法了,但怎样才能初始化呢? 1.37 能够初始化联合吗? 第2章 结构、联合和枚举 结构声明 2.1 structx1{ };和typedefstruct{ }x2;有什么不同? 2.2 这样的代码为什么...
为PDF文件增加了目录,便于快速浏览。 摘录一些不知道以及没有做到的: ...TODO很不错,有时候,注释确实是为了标记一些未完成的或完成的不尽如人意的地方,这样一搜索,就知道还有哪些活要干,日志都省了。
o 2.14 我总算弄清除函数指针的声明方法了, 但怎样才能初始化呢? * 3. 结构、联合和枚举 o 3.1 声明 struct x1 { ...}; 和 typedef struct { ...} x2; 有什么不同? o 3.2 为什么 struct x { ...}; x ...
这个作业将让你去练习建立一些简单的类和使用C++的基本功能,包括:封装,引用,动态内存开辟, 简单构造函数和析构函数和const。 下面给的程序片段未经过编译或调试. 做出合理的错误修正是你任务的一部分。 一般的,...
// 读取测试文件中的空格,将文件指针指向下一行; printf("输入文件是:\n"); //回显获得的缓冲区的数目信息; printf("%d \n",(int) n_Buffer_or_Critical); //提取每个线程的信息到相应数据结构中; while...
为了暂停(yielding)C++函数,(不支持在C++侧和Lua侧传送数据块),你可以使用 yield 策略. 接受 object 参数的resume_function()的重载版本要求对象必须是一个协程对象.(thread) lua_State* thread = lua_newthread(L...
在计算机科学发展过程中,早期数据结构教材大都采用PASCAL语言为描述工具,后来出现了采用C语言为描述工具的教材版本、至今又出现了采用C++语言为描述工具的多种教材版本。本教实验指导书是为已经学习过C++语言的...
1.14 我总算弄清除函数指针的声明方法了, 但怎样才能初始化呢? . . 5 2 结构、联合和枚举7 2.1 声明struct x1 f . . . g; 和typedef struct f . . . g x2; 有什么不同? . 7 2.2 为什么struct x f . . . g; x ...
MFC类库中提供了丰富的CObList类的成员函数,此程序主要用到的成员函数如下:(1) 构造函数,为CObject指针构造一个空的列表。 (2) GetHead(),访问链表首部,返回列表中的首元素(列表不能为空)。(3) AddTail(),在...
你可以使用窗口管理函数创建和使用窗口来显示输出、提示用户进行输入以及完成其他一些与用户进行交互所需的工作。大多数应用程序都至少要创建一个窗口。 应用程序通过创建窗口类及相应的窗口过程来定义它们所用窗日...
/// 构造函数,实例化类的运行 /// </summary> public HKWS() { mdd = new NetSDK.NET_DVR_MATRIX_DYNAMIC_DEC(); dci = new NetSDK.NET_DVR_MATRIX_DEC_CHAN_INFO(); ClientInfo = new ...