__cdecl与__stdcall概念中的调用者和被调用者是什么意思?
我只学过C入门,只做过课后习题,最近刚学windows下的C。
但书上第一个程序我就看不懂了
int WINAPI WinMain()
这里的WINAPI我从来没见过这种用法,网上查了下其实是指定__cdecl或__stdcall等这样的函数调用约定,但即使是看了大篇文章后我还是不懂,主要是这些话:
不论__stdcall还是__cdecl函数参数都是从右向左入栈的,并且由调用者完成入栈操作。对于__stdcall方式被调用者自身在函数返回前清空堆栈;而__cdecl则由调用者维护内存堆栈,所以调用者函数生成的汇编代码比前一种方式长。
我想知道上述的调用者/被调用者
是人(我自己)还是函数?这些入栈/清空堆栈的操作指的是不是要在申请动态内存后要记得free()掉?不然指的是什么?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你都已经查到 __stdcall这一步了,再往下多查一步不就知道了么。
调用者(caller)和被调用者(callee)都是指函数。入栈清栈指的是函数调用参数传递的方式。清栈职责在caller这边,意思就是:
转换成汇编是:
如果职责在callee那边,上面最后一行就移到
foo
中:后一种方式一个函数只能接受固定个数的参数,因为编译时就需要确定
add x,%esp
中x
到底是几。哦,对了,这些都是编译器的行为,程序员根本不需要关心。
学编程最重要的是了解运行环境、如操作系统、编译器。语言本身并不太重要。
有一个必需掌握的能力就是调试能力,要有汇编级调试能力。有了这个能力,你的问题调试跟踪一下能找到答案了。
很多时候,要提高这种能力,可以通过学习逆向工程获得。
国内看雪学院http://www.pediy.com/是个不错的地方。
WINAPI本身就宏定义,也就是 #define WINAPI __stdcall 当然这个在Mac下面不一样。几乎所有的Win32 API函数都是这种类型。编译后的程序体积小些,名字改编不一样。还有一个明显的特征,比如printf支持变长,而WINAPI的是不支持变长的,因为被调用者不知道传入参数是多少,不懂的如何去清理,所以这里printf得是__cdecl