函数的调用方式分析
2015-10-22 11:13
183 查看
闲来无事,研究了一下VC中的三种函数调用方式 cdcel stdcall fastcall
现将结论公布如下:
1 cdcel调用方式,调用之前的参数压栈是由调用函数完成,函数调用结束之后,由调用函数弹出堆栈中的参数。但是cdcel的esp指针确是需要由调用函数来完成恢复的。
2 stdcall ,调用之前的参数压栈是由调用函数来做,子函数来弹出栈中的参数。相当于,调用函数push,子函数pop。由子函数恢复esp指针。
3 fastcall ,参数的压栈和参数的弹出都是由子函数来完成的,相当于 子函数 既负责push 也负责pop,子函数恢复esp指针。
总体上讲,cdcel 和fastcall比较正式一点,因为写程序都讲究谁申请谁释放,而stdcall方式却将这种成对的操作push和pop在两个模块中来做,虽然这都是编译器自动来完成的。但是cdcel的esp指针却是由调用函数来恢复。
另外:这次分析之后的心得就是:程序中的变量如果不是全局的那么变量的空间都是分配在栈之上的,这个栈的地址是由sp寄存器指示的,每次函数调用,系统都会在esp之后的一定空间(我测试的是esp-40)重新建立栈空间,子函数中的变量就会在这个新的栈上。而且调用函数和被调用函数的中变量的空间分配地址比较接近,因为每次建立新的栈大概也只有40H这么个大小的距离,但是全局变量就不一样了,我当时测试的全局变量地址是00424d8c这个位置,而栈区的变量地址是0013FF84附近,还有就是程序的code应该是根据程序的文件组织结构编译的,并且由EIP进行指示,每次调用子函数的时候,当前eip就会被压栈,子函数结束了就弹出EIP,这样就可以返回到调用子函数的地方了。
还不明白的地方是:在新的栈建立的时候,栈底部为什么要用10H个DWORD,就是64个字节来填充一下,还有就是调用子函数的时候,先是call一下,但是call的不是子函数的地址,而是跳到一个地址之后再jmp一下到子函数的地址。
现将结论公布如下:
1 cdcel调用方式,调用之前的参数压栈是由调用函数完成,函数调用结束之后,由调用函数弹出堆栈中的参数。但是cdcel的esp指针确是需要由调用函数来完成恢复的。
2 stdcall ,调用之前的参数压栈是由调用函数来做,子函数来弹出栈中的参数。相当于,调用函数push,子函数pop。由子函数恢复esp指针。
3 fastcall ,参数的压栈和参数的弹出都是由子函数来完成的,相当于 子函数 既负责push 也负责pop,子函数恢复esp指针。
总体上讲,cdcel 和fastcall比较正式一点,因为写程序都讲究谁申请谁释放,而stdcall方式却将这种成对的操作push和pop在两个模块中来做,虽然这都是编译器自动来完成的。但是cdcel的esp指针却是由调用函数来恢复。
另外:这次分析之后的心得就是:程序中的变量如果不是全局的那么变量的空间都是分配在栈之上的,这个栈的地址是由sp寄存器指示的,每次函数调用,系统都会在esp之后的一定空间(我测试的是esp-40)重新建立栈空间,子函数中的变量就会在这个新的栈上。而且调用函数和被调用函数的中变量的空间分配地址比较接近,因为每次建立新的栈大概也只有40H这么个大小的距离,但是全局变量就不一样了,我当时测试的全局变量地址是00424d8c这个位置,而栈区的变量地址是0013FF84附近,还有就是程序的code应该是根据程序的文件组织结构编译的,并且由EIP进行指示,每次调用子函数的时候,当前eip就会被压栈,子函数结束了就弹出EIP,这样就可以返回到调用子函数的地方了。
还不明白的地方是:在新的栈建立的时候,栈底部为什么要用10H个DWORD,就是64个字节来填充一下,还有就是调用子函数的时候,先是call一下,但是call的不是子函数的地址,而是跳到一个地址之后再jmp一下到子函数的地址。
相关文章推荐
- vim的多文件编辑
- 关于如何在服务器上搭建tomcat并发布自己的web项目
- windows 编程博客
- 多线程学习之多线程访问共同资源(队列,多线程,锁机制)实例
- 利用jQuery和CSS实现环形进度条
- 浅析SOA面向服务架构
- word-break:break-all、word-break:break-work和work-wrap:break-work的区别
- Head First C# 实验室 赛狗日
- 保证服务既能长期运行,又能调用服务里的方法的方案
- 在ActiveX控件中使用Mscom控件
- ADO 访问sybase数据库
- 10.22 我的代码终于破800行................
- 随摘
- test markdown 写博客
- int 和Integer的区别
- sublime text
- Linux 新建用户、用户组,给用户分配权限(转载)
- 重装系统可能遇到的麻烦
- 宏观软件学之于微观软件学
- Android已安装了存在签名冲突的同名数据包