__cdecl调用 C语言变参
来源:互联网 发布:淘宝一族的货在哪进货 编辑:程序博客网 时间:2024/06/05 09:25
__cdecl调用
在C语言中,函数调用支持不定参数,例如printf函数,可以不知道参数的个数,eg:
void err_info(const char *fmt, ...)
{
va_list ap;
va_start(ap, fmt);
vfprintf(stderr, fmt, ap);
va_end(ap);
}
这是如何实现的呢?如何支持变参的呢?
下面简要介绍下__cdecl调用方式,当然还有很多其他的调用方式,不过目前用不到
函数调用需要关注的几个方面:
1、函数调用时参数是如何保存的?
2、是调用者来清理函数调用还是被调用者来清理函数调用?
3、函数调用时参数的顺序是怎样的?
4、可能会用到哪些寄存器?
先说第一个问题,这个是很容易的,大家都知道C语言中是用栈来保存函数调用时的参数的
下面再分析其他几个问题:
在__cdcel标准中规定:
1、函数调用的参数入栈顺序是从右到左,即先压栈最右边的参数,最后压栈最左边的参数
2、在函数调用结束后用调用者来清理栈
3、调用过程中一般会用到eax、ebx、ecx等寄存器
void func(int a, int b)
{
...
}
int main(void)
{
...
func(1,2);
...
}
下面以这个例子来说明:
在调用的过程中由于是从右到左入栈,所以压栈的顺序是先2后1,用汇编可以描述为:
push 2
push 1
main函数对应的汇编大概是:
push 2
push 1
call func
add esp, 8 //清理栈,因为在调用过程中esp指针向下(或者说是向低地址)移动了8个字节
ret
这是调用顺序上
基于上面的几点我们就可以理解C语言中是如何实现变参函数的调用了:
1、由于函数调用是从右到左入栈的,因此函数调用时最左边的参数是最后一个入栈的,这样就可以函数调用时最左边的参数位置了
2、由于有format的指定,每个参数的大小是可知的,例如%d表示是int型,占用4个字节等
3、根据上面的两项就可以取出函数参数了。首先根据最左边参数(此处的含义是最后一个确定参数,也就是该参数后面的参数都是可变参数)
(例如
void func(char *arg1, char *arg2, ...)
那么最左边的参数意思就是arg2,因为它是最后一个确定参数
)
的位置可以找到函数调用时最左边的参数,然后根据每个参数的大小,移动esp指针(一般是向高地址移动),就可以依次取出其他所有参数了
wiki上介绍:http://en.wikipedia.org/wiki/X86_calling_conventions
- __cdecl调用 C语言变参
- c语言变参
- CALLBACK--_stdcall(PASCAL调用方式),VS默认是C语言调用方式即__cdecl
- c语言变参函数-
- C语言变参技术
- C语言变参技术
- C语言变参,记录
- C语言变参使用
- C语言的变参
- C语言变参使用
- C语言变参处理
- c语言变参函数
- C语言变参函数
- C语言变参问题
- C语言变参函数
- C语言变参使用
- C语言变参函数
- C语言的变参函数设计
- MYSQL全角半角的主键冲突问题.
- dataTable内实现排序
- 定位Oracle kill命令未实际中断的Session/Process
- List转DataTable 反射方式
- C#实现接口的实例解析
- __cdecl调用 C语言变参
- 在网页中插入flash的时候能在IE中显示但是不能在火狐里显示的问题
- 关于CButton关联整型变量的问题
- VLAN Security White Paper
- 如何将 SQL SERVER 彻底卸载干净
- DPInst and DIfx usage
- .Net下修改文件夹或文件的ACL安全权限
- 网址之家推广
- 关于UpdateData