打印
[ZLG-ARM]

可变参数函数的实现原理 (转)

[复制链接]
1536|1
手机看帖
扫描二维码
随时随地手机跟帖
跳转到指定楼层
楼主
FVJFIFE|  楼主 | 2011-11-24 21:49 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
以下内容节选自“底层工作者手册之嵌入式操作系统内核”中的4.3节,这本手册讲述的是WanlixMindows操作系统内核原理,更多资料请登陆www.ifreecoding.com下载。
在学习C语言时,我们都使用过printf函数,这个函数可以根据个人需要,很灵活的向显示器终端打印数据,比如,我们可以按照下面的方式输出:
printf("Wanlix & Mindows");
printf("%d, %c", i, j);
不知道你注意过没有,printf函数的参数个数是可变的,上面的第一个例子只有1个参数,第二个例子有3个参数,这点与我们一般所使用的函数是不同的。在Mindows中,我们仿造printf函数,将向内存打印的函数DEV_PutStrToMem也编写成一个参数可变的函数,下面我们一起来看看这是怎么实现的。
参数可变的函数原型定义为:
void DEV_PutStrToMem(U8* pvStringPt, ...);
其中比较特别的是“...”,这三个点表示省略的参数。可变参数函数的原理非常简单,可变参数函数的参数不像我们前面讲过的那样,使用R0~R3寄存器传递参数,而是直接使用堆栈传递参数,而且这些参数都是连在一起存放的,而函数原型中第一个参数是固定的,我们可以获取到第一个参数的地址&pvStringPt,然后将这个地址加4就可以得到第二个参数的地址,再加4就是第三个参数的地址,依次类推,这样就可以获取到任意多的参数地址了,有了参数地址那么获取参数也就不成问题了。那么DEV_PutStrToMem函数怎么知道究竟有多少个参数呢?那些可变的参数是需要转换成第一个参数中%号后面的格式的,这样,我们只需要查找%号的个数确定可变参数的个数了。
file:///C:/DOCUME~1/ADMINI~1/LOCALS~1/Temp/ksohtml/wps_clip_image-30547.png
图 43 可变参数函数
可变参数函数的原型可以有多种形式,但必须要保证:
1.必须有第一个参数,通过这个参数才能获取到参数存放在栈中的首地址,后面的参数才是可变的。
2.在设计可变参数时需要能体现出可变参数的个数,如上面查找第一个参数中%号的方法,或者将第一个参数定义为可变参数的个数,或者其它方式。
在C语言标准头文件stdarg.h里面已经为可变函数定义了几个宏,使用这些宏也可以实现可变参数函数,原理都一样, 细节不再介绍了。

相关帖子

沙发
gabys| | 2011-11-25 20:42 | 只看该作者
FVJFIFE发表的这些东西,很实用。

使用特权

评论回复
发新帖 我要提问
您需要登录后才可以回帖 登录 | 注册

本版积分规则

0

主题

897

帖子

1

粉丝